Skip to the content.

useReducer

back to main

- what is useReducer ?

counter example from the useState section, rewritten to use a reducer:

const initialState = {count: 0};

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

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

Note

What are two ways to set the initial state?

1-The simplest way is to pass the initial state as a second argument: ex :

  const [state, dispatch] = useReducer(
    reducer,
    {count: initialCount}
  );

2-Lazy initialization : you can pass an init function as the third argument. The initial state will be set to init(initialArg). ex :

function init(initialCount) {
  return {count: initialCount};
}

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

function Counter({initialCount}) {
  const [state, dispatch] = useReducer(reducer, initialCount, init);
  return (
    <>
      Count: {state.count}
      <button
        onClick={() => dispatch({type: 'reset', payload: initialCount})}>
        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

when to Use useReducer ?

when you move past managing primitive data, i.e., a string, integer, or Boolean, and instead must manage a complex object, like with arrays and additional primitives, you’re likely better off with useReducer

## what does useReducer expect to receive as a parameter?

Basically: useReducer: expect 2 parameters, (a) a function (known as the reducer function), and (b) the initial value for the state. The reducer function will be called to modify the state whenever you call fn with some value. And the value passed to fn will be passed through to the reducer function (as the second parameter)

## What does useReducer return?

the useReducer hook returns two things: the state, and a function called dispatch. This is pretty similar to useState, which also returns the state and a function to modify the state. const [ state, dispatch] = useReducer(reducer, initialState);