React: Introduction to useReducer hook

React: Introduction to useReducer hook

In this article, I'm assuming that you have at least some knowledge of using React and want to explore React Hooks.

useReducer

This hook is used to handle complex state in our application. Inspired by redux state management pattern (If you're not familiar with redux you can check it here). It is used to store and update states, just like the useState hook. It accepts reducer function as its first parameter and the initial state as the second.

It returns an array that holds the current value and a dispatch function in which you can pass an action to the reducer function.

Syntax:

const [state, dispatch] = useReducer(reducerFn, initialState)

state - value of the current state.

dispatch - is the method that will be used to call the reducerFn. It accepts an object that represents the type of action. Send the type of action to the reducer function and update the state.

reducerFn - a function that returns some state data, triggered by action type.

initialState - initial value of state.

Understand by Example

In the following example, we will create a simple app that will increment and decrement counter by pressing the button. We will be using the useReducer for this.

import { useReducer } from 'react';

const initialState = {
  counter: 0
};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, counter: state.counter + 1 };
    case 'decrement':
        return { ...state, counter: state.counter - 1 };
    default:
      throw new Error();
  }
}

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div style={{ margin: 12 }}>
      <div> {state.counter}</div>
      <button onClick={() => dispatch({ type: 'increment' })}>
        Increment
      </button>
      <button onClick={() => dispatch({ type: 'decrement' })}>
        Decrement
      </button>

    </div>
  );
}

export default MyComponent;

Here we import the useReducer hook at the top of the component. We define the initialState and reducer function outside our component since all the values will be passed using the dispatch method.

The reducer function takes two arguments: state and action. state holds the value of current state, on initial render it's value is the initialState object, and action is used to check what action which condition to trigger. type is the property we’re passing from the dispatch action to determine which condition to trigger inside the reducer function.

The component will be re-rendered every time counter state value changes.

When to use useReducer?

In the above code example, you can see that useReducer implementation is much longer than useState hook. It is prefer to use useReducer if the state of component has a complex structure, think of object with many properties.

Is useReducer a replacement for Redux?

The answer is No. It is not intended to replace redux, instead it should be used in components that have complex state logic on it. Some might tend to think that useReducer feature is intended to replace the redux. In fact, useReducer is restricted to component only.

And that's all folks. Thanks for reading!

If you have any question or feedback. Feel free to comment below.