3 steps to create custom state management library with React Hooks and Context API
Rahul Sharma
Posted on March 15, 2022
In this article, I will introduce the React Context API for state management and create a similar solution as Redux without using a third-party library.
React Context API
It’s actually not a new idea. Context API as part of React for a long time, but only in an experimental state.
Since React 16.3.0 it’s officially stable and ready to use in production.
Without further ado, here are the steps
Step: 1 Creating Provider and connect function (same as react-redux connect and Provider) using useReducer, createContext & useContext
import React, { useReducer, createContext, useContext } from "react";
const initialState = {};
// Create App Context
export const Context = createContext(initialState);
export const Provider = ({ children, reducers}) => {
const defaultState = reducers(undefined, initialState);
if (defaultState === undefined) {
throw new Error("reducer's should not return undefined");
}
const [state, dispatch] = useReducer((_state, _action) => {
return reducers(_state, _action);
}, defaultState);
return (
<Context.Provider value={{ state, dispatch }}>
{children}
</Context.Provider>
);
};
export const useDispatch = () => useContext(Context).dispatch;
export const useSelector = (callback) => {
const state = { ...useContext(Context).state };
return callback ? callback(state) : state;
};
Step: 2 Connect react app to above created Provider
const actionMap = {
INCREMENT: (state, action) => ({ ...state, count: state.count + 1 }),
DECREMENT: (state, action) => ({ ...state, count: state.count - 1 }),
};
const countReducer = (state = { count: 0 }, action) => {
const exec = actionMap[action.type];
return exec ? exec(state, action) : state;
};
const reducers = { countReducer };
const App = () => (
<Provider reducers={reducers}>
<Component />
</Provider>
);
Step: 3 Connect component to react Context
const Component = () => {
const dispatch = useDispatch();
const { count } = useSelector((state) => state.countReducer);
return (<h3>Context State: {count} </h3>)
}
Live Demo: Here
Bonus Tip
export const combineReducers = (reducers) => {
const entries = Object.entries(reducers);
return (state = {}, action) => {
return entries.reduce((_state, [key, reducer]) => {
_state[key] = reducer(state[key], action);
return _state;
}, {});
};
};
Got any questions or additional? please leave a comment.
What is Next
React best practices and patterns to reduce code
Rahul Sharma ・ Mar 15 '22
How to solve REST API routing problem with decorators?
Rahul Sharma ・ Mar 23 '22
Catch me on
Youtube Github LinkedIn Medium Stackblitz Hashnode HackerNoon
Posted on March 15, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
March 15, 2022