react-context-reducer
React Context + useReducer = Hooks version of Redux. This library is intended to be a light weight stand-in for Redux.js.
Features
- Same great features found in Redux
- Create a data store using
createContextReducer()
. - Simplify reducer complexity with
combineReducers()
. - New
combineActions()
validate and consolidate all your actions into one export. - Use existing Redux middlewares or create your own.
- Take advantage of the included
reduxDevTools()
ordispatchLogger
middleware.
- Take advantage of the included
- Use a simple
<Provider />
HoC to register the context store with your app. - Connect your components to your stores state with
connect()
HoC,use()
Hook, - Use
getState()
ordispatch()
to interact with your store outside a react component. - Create as many stores as you need with
createContextReducer()
or use one super store by combining your reducers. - Only render when props change using
React.memo()
. - Developer friendly with fail fast helpful debugging messages.
- Use
withTypeCheck()
to describe your action and store shape.
- Use
- Lightweight under 5kb in production
Installing
Using npm:
$ npm install react-context-reducer
Also install the required peer dependancies if you have not already done so:
$ npm install react$ npm install prop-types
Core API
createContextReducer(ContextKey, reducer, middlewares)
- Creates a Context store object with the following properties:
ContextKey: ContextKey /* name of the store. */ Context /* React Context Object. */ Provider /* The Provider HoC. */ /* React Hook to use the store. returns [state, dispatch] - keys (optional) array of keys to return from the state. */ /* The Connect HoC - mapContextToProps(...) function to map context [state, dispatch] to props. - keys (optional) array of keys to return from the state. - options (optional) object {useMemo = true} */ /* Returns the current state of the store. */ /* Dispatch an action to your store. */
combineReducers({...})
- Split up complex reducers into smaller chunks. Works exactly like redux implementation Redux of combineReducers().combineActions({...})
- Combines actions similar to reducers and validates all your actions for uniqueness. Helps reduce the number of files you need to include in larger apps.withTypeCheck(actionName or reducer, propTypes schema)
- Define your action payload shape or reducers state shape by wrapping it withTypeCheck.
Middleware API
The middleware api sits between every dispatch call to your store. This allows for advanced features such as logging, analytics, crash reports, etc...
store.getState()
- Get the current state of the store. (before the reducer has been resolved)store.dispatch(action)
- Dispatch a new action before (or after with async callback) the current dispatch completes.next(action)
- Process the next middleware in the chain. (You can modify action before passing it to the next middleware in the chain)action
- The passed down action.
// log every dispatch to the console { console; console; console; const result = ; console; console; return result; };
Example
First we need to create a context store using createContextReducer().
// ./AppStore.jsimport propTypes from 'prop-types';import createContextReducer reduxDevTools withTypeCheck from 'react-context-reducer'; // create your actions.const AppStoreActions = Add: ) Subtract: ; // create your reducer.const reducer = state = 0 action switchactiontypes case AppStoreActionsAdd: return state+1; case AppStoreActionsSubtract: return state-1; default: return state; ; // Create the context store and export it. "AppStore" // store name // reducer // middlewares;
Now we can provide the context store to the app by wrapping it with AppStore.Provider
.
// ./app.jsimport React from 'react';import AppStore from './AppStore';import MyComponent from './MyComponent'; const App = props return <AppStore.Provider> <MyComponent /> </AppStore.Provider> ; ;
Connect our store to a component that needs access to state and dispatch using the AppStore.connect()
HoC.
// ./MyComponent.js - AppStore.connect() HoCimport React from 'react';import AppStore AppStoreActions from './AppStore'; const MyComponent = props const state dispatch = props; return <div> <button =>Add</button> <button =>Subtract</button> state </div> ; MyComponent;
Alternatively you can use the AppStore.use(selectors)
hook to also gain access to the stores state and dispatch.
// ./MyComponent.js - AppStore.use() hookimport React from 'react';import AppStore AppStoreActions from './AppStore'; const MyComponent = props const state dispatch = AppStore; // hook return <div> <button =>Add</button> <button =>Subtract</button> state </div> ; ;
If everything was coded up correctly you should now see two buttons and the state value. Each time a button is pressed you will also see the action being logged to the console because of the reduxDevTools()
middleware.
View Examples (Work In Progress) https://sheaivey.github.io/react-context-reducer/