Akhila Ariyachandra

Using useReducer with useContext

Posted on 19th June 2021

5 min read

67 views

useReducer is a hook we can use to manage an advanced state and useContext is used to share state between components.

If we combine both of them we can more easily manage multiple state across components without needing a separate state management library.

This post will not be an introduction to useReducer and useContext, so I’ll include links to both of them if you want to learn about them first.

Setting up the context

Let’s start with creating the context.

Create the context folder and in it the ValueContext.jsx file.

src\context\ValueContext.jsx

jsx

Then define the initial state.

src\context\ValueContext.jsx

jsx

After that we’ll create the reducer with our actions. For example we’ll set up two actions, one to set the new value and one to clear it.

src\context\ValueContext.jsx

jsx

A couple of notes about the reducer.

  • The default value of the state will the initialState.
  • If we want to change the value of the state, it will be passed through the payload field in the action object (as we’ll see later when we try to set a new value).

Next we’ll need to initialize the context.

src\context\ValueContext.jsx

jsx

We need to pass the value to be shared as the argument for createContext. Since we need both the value(state) and a way of changing it(dispatch), both will be passed as an object to createContext.

After that let’s create a wrapper for the root component so that the state can be shared with it’s child components.

src\context\ValueContext.jsx

jsx

The state and dispatch from useReducer will be given as an object to the value prop of ValueContext.Provider.

To finish setting up the context, all we need to do is to wrap the root component with ValueProvider

src\context\App.js

jsx

Using the shared state

Now that we’ve set up the context, let’s create a couple of components to see how the state will be shared.

Input component

To start create Input.jsx in components.

src\components\Input.jsx

jsx

Then import the ValueContext and get it’s value using useContext.

src\components\Input.jsx

jsx

Next let’s add an input and a handler for it.

src\components\Input.jsx

jsx

We can change the state using dispatch. The action type will be "SET_VALUE" (like we defined in reducer).

To finish up the the Input component, let’s add a button to clear the state and add it to the root component.

src\components\Input.jsx

jsx

src\context\App.js

jsx

Display component

Let’s create a simple so we can see the state being updated across components.

src\components\Display.jsx

jsx

Then add it to the root component.

src\App.js

jsx

Conclusion

All the code is available on CodeSandbox.

This is a pattern is started using more of recently. If you would like to suggest an improvement leave a comment below.

Leave a Reaction below