DEV Community

Karl Castillo
Karl Castillo

Posted on

React: useReducer

Previously we talked about useState but what if your state is more complicated. That's when useReducer comes into play. useReducer is usually written similar to the Flux Architecture where you deal with a store (the state), actions and dispatches.

useReducer takes in 3 arguments -- reducer, initial state, lazy state initialization. It the returns an array consisting of the state and a dispatch.

const reducer = (state, action) => { ... }

const App = () => {
  const [state, dispatch] = useReducer(reducer, { counter: 0 })
  ...
}
Enter fullscreen mode Exit fullscreen mode

Unlike useState we need to a little more for us to manipulate state. The way state is updated when using useReducer is for us to return the new state from the reducer.

const reducer = (state, action) => {
  return state.counter + 1
}
Enter fullscreen mode Exit fullscreen mode

So how do we call the reducer? This is where dispatch comes into play. Dispatch is a function that passes whatever you pass into the reducer's second parameter.

const reducer = (state, action) => {
  console.log(action)
  return state
}

const App = () => {
  const [state, dispatch] = useReducer(reducer)

  dispatch('hello') // hello
  dispatch({ greeting: 'hello' }) // { greeting: 'hello' }
}
Enter fullscreen mode Exit fullscreen mode

Knowing that we pass anything to the reducer, the true power of the reducer is for us do different types of actions (ie. add, minus, set, etc.).

const reducer = (state, action) => {
  switch(action.type) {
    case "set":
      return action.payload.number
    case "add":
      return state.counter + action.payload.number
    case "minus":
      return state.counter - acount.payload.number
    default:
      throw new Error(`Unknown action: ${action.type}`)
  }
}

const App = () => {
  const [state, dispatch] = useReducer(reducer, { counter : 0 })
  ...
  dispatch({ type: "set", payload: { number: 1 })
  dispatch({ type: "add", payload: { number: 1 })
  dispatch({ type: "minus", payload: { number: 1 })
  ...
}
Enter fullscreen mode Exit fullscreen mode

IMPORTANT: It's important to return the state even if you didn't manipulate it.

Looking at the example code above, you don't have to follow the same structure. Feel free to experiment what you think would for your use case.

Oldest comments (0)