Clue Mediator

useReducer hook for multiple states in the React

📅December 31, 2020

Today we will show you how to use the useReducer hook for multiple states in the React component. In the previous article, we have taken a simple counter example using useReducer hook.

Here, we will take multiple state object and manage states using a single useReducer hook. The user interface of your demo will look like below.

Output - useReducer hook for multiple states in the React - Clue Mediator

Output - useReducer hook for multiple states in the React - Clue Mediator

useReducer hook for multiple states

  1. Create react application and add useReducer
  2. Use complex state and action
  3. Add second counter
  4. Output

1. Create react application and add useReducer

Let’s create a simple react app by executing the following command.

npx create-react-app usereducer-multiple-states-react-hook

Now, create a counter example using the useReducer react hook. Refer to the previous article.

You may have noticed that we have taken the counter state directly as an integer type, but in the next step, we will create a multiple counter example using the object type.

2. Use complex state and action

Let’s update the state and reducer method where we will manage the multiple state based on the `action.type` and the `action.value`.

const initialState = {
  counter1: 0,
  counter2: 10
};

const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { ...state, counter1: state.counter1 + action.value };
    case 'decrement':
      return { ...state, counter1: state.counter1 - action.value };
    case 'reset':
      return initialState;
    default:
      return state;
  }
}

In the above code, we have used the Spread Operator to update the individual state value and return the state object.

Let’s update the button click and display value.

const [state, dispatch] = useReducer(reducer, initialState);

return (
...
<span>First Counter: {state.counter1}</span>
<button onclick="{()" ==""> dispatch({ type: 'increment', value: 1 })}>Increment</button>
<button onclick="{()" ==""> dispatch({ type: 'decrement', value: 1 })}>Decrement</button>
<button onclick="{()" ==""> dispatch({ type: 'reset' })}>Reset</button>
...
)

3. Add second counter

In this step, we will increase & decrease the `counter2` by `10` using the same reducer. For that we have to add a few more action types in the reducer function.

…
...
const reducer = (state, action) => {
  switch (action.type) {
    ...
    ...
    case 'increment2':
      return { ...state, counter2: state.counter2 + action.value };
    case 'decrement2':
      return { ...state, counter2: state.counter2 - action.value };
    ...
    ...
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div class="App">
      ...
      ...
      <span>Second Counter: {state.counter2}</span>
      <button onclick="{()" ==""> dispatch({ type: 'increment2', value: 10 })}>Increment 10</button>
      <button onclick="{()" ==""> dispatch({ type: 'decrement2', value: 10 })}>Decrement 10</button>
    </div>
  );
}

In the above code, we have passed the value as a `10` in the `dispatch` method to update the `counter2`.

4. Output

Let’s combine all code together and see how it looks.

App.js

import React, { useReducer } from "react";

const initialState = {
  counter1: 0,
  counter2: 10
};

const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { ...state, counter1: state.counter1 + action.value };
    case 'decrement':
      return { ...state, counter1: state.counter1 - action.value };
    case 'increment2':
      return { ...state, counter2: state.counter2 + action.value };
    case 'decrement2':
      return { ...state, counter2: state.counter2 - action.value };
    case 'reset':
      return initialState;
    default:
      return state;
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div class="App">
      <h3>useReducer for multiple states - <a href="https://www.cluemediator.com" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3>
      <span>First Counter: {state.counter1}</span>
      <button onclick="{()" ==""> dispatch({ type: 'increment', value: 1 })}>Increment</button>
      <button onclick="{()" ==""> dispatch({ type: 'decrement', value: 1 })}>Decrement</button>
      <button onclick="{()" ==""> dispatch({ type: 'reset' })}>Reset</button>
      <br><br>
      <span>Second Counter: {state.counter2}</span>
      <button onclick="{()" ==""> dispatch({ type: 'increment2', value: 10 })}>Increment 10</button>
      <button onclick="{()" ==""> dispatch({ type: 'decrement2', value: 10 })}>Decrement 10</button>
    </div>
  );
}

export default App;

Run the application and check the output in the browser.

That’s it for today.
Thank you for reading. Happy Coding..!! 🙂

Demo & Source Code

Github Repository StackBlitz Project