How to create a Redux like pattern with Context API and useReducer

vvkkumar06

Vivek Kumar

Posted on December 26, 2023

How to create a Redux like pattern with Context API and useReducer

In most of the React js projects, we tend to use Redux for state management but sometimes we don't want to configure Redux in some of the applications, probably because the application size is not that big or we don't want to install too many third party libraries considering the bundle size.

Even without using Redux, we can configure the design pattern we use with Redux in our React application.

So in this tutorial, we will be using the Context Api and the useReducer hook.
If you are not aware of the Context API and the useReducer hook, you should check out the React official documentation before proceeding further. Just a basic understanding of these two will be enough.

Step 1

Alright, in our react app directory, we will be creating one store folder, that will be responsible for holding all the redux-specific files. When I say redux, it is not a redux library but a kind of system that redux follows.

Initial folder structure

Step 2

We will create a file storeProvider.js inside store folder and create a context and a component that will be just a wrapper of Context Provider.

Store Provider initial setup

Step 3

Now that we have a StoreProvider, we can use this in our root file which is index.js as shown below.

Providing in index

Step 4

Similar to useSelector in the react-redux library, we will be creating a custom hook that will be responsible for providing store values.
We will create a hook inside the store folder i.e. 'useStore.js'

useStore custom hook
And why we are using callback here, so sometimes we want to access specific property from the store object. If you recall useSelector hook, there we used to do something like
const users = useSelector(state => state.users);
Similarly, we will be using,
const users = useStore(state => state.users);

Step 5

Now in our App component, we can verify the store values we are providing.
To do this, let's add a dummy state in our store, for that we will be updating our storeProvider as given below:

Store provider with dummy state
And then in the app.js component(we can use any nested component), we can update as shown below:

App js with useStore
Now, if we check the browser's console, we will get the logs for the state.

dummy state logs

Step 6

So far, we have used hard-coded store property, but in real applications, we have many reducers. So, we will be creating our two reducers(count and users) inside a '/store/reducers/' folder.

Count reducer

users reducer

Step 7

It's time to use the useReducer hook, for that we will have to update the storeProvider and we will be passing dispatch object in context value.

useReducer

Step 8

You might have noticed, that we used rootReducer function, the reason behind that is we can not pass multiple reducers in the useReducer hook, so we need to find a way to combine multiple reducers into one reducer i.e. rootReducer.
We will create one index.js file in '/store/reducers' as given below:

Root reducer
The parameters we are passing inside reducers are their state and our dispatch action object. Since we will be having switch cases in each reducer, it won't impact the count reducer even if it gets the users' action object.

Step 9

To verify this, we can configure our React App component

React app component with dispatch

Final logs

When we click on 'Increment' button, we will notice we are getting both store values.

Now we have successfully configured Redux free global store management system.

💖 💪 🙅 🚩
vvkkumar06
Vivek Kumar

Posted on December 26, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related