React useReducer hook – A complete guide for beginners

What is useReducer hook?

useReducer is a hook in React that allows you to manage more complex states in your application. It defines a function called a “reducer” that takes in the current state and an action and returns a new state based on that action. You can use the useReducer hook to initialize your state and create a dispatch function that you can use to update your state based on the actions defined in your reducer function.

When to use useReducer hook in react?

  • The useReducer hook is useful when you have a state that needs to be updated based on multiple actions, or when your state is complex and difficult to manage with useState alone.
  • If you need to update the state frequently, useReducer can help optimize performance. This is because useReducer returns a new state object only when the state has actually changed, rather than on every render like useState.
  • Overall, useReducer can help make your code more organized and easier to understand by separating your state management into smaller, more manageable pieces.
  • If you need to share the state between multiple components, useReducer can be a good choice. You can pass the state and dispatch function down through your component tree using props or context, and any child component can update the state using the dispatch function.

Read: Build a Simple ToDo App using React JS Functional Components and Hooks

Here’s an example using a todo list. Let’s say you have an array of todo items, and each item has a title and a boolean value for whether it is completed or not:

const todos = [
  { id: 1, title: 'Buy milk', completed: false },
  { id: 2, title: 'Walk the dog', completed: true },
  { id: 3, title: 'Clean the house', completed: false }
];

With useState, you might have a state variable like this:

const [todoList, setTodoList] = useState(todos);

Then, you could map over the todoList to display your todos and use the setTodoList function to update the state when a todo is completed or deleted.

But with useReducer, you can create a more structured way of updating your state. Here’s an example:

function todoReducer(state, action) {
  switch (action.type) {
    case 'COMPLETE_TODO':
      return state.map(todo => {
        if (todo.id === action.payload.id) {
          return { ...todo, completed: !todo.completed };
        }
        return todo;
      });
    case 'DELETE_TODO':
      return state.filter(todo => todo.id !== action.payload.id);
    default:
      return state;
  }
}

const [todoList, dispatch] = useReducer(todoReducer, todos);

In this example, we define a todoReducer function that takes in a state and an action and returns a new state based on the action. The dispatch function is used to update the state based on the action.

Read: What are Hooks in ReactJS? Important ReactJS Hooks List

Now, let’s say you want to toggle a todo item’s completed value. You can use the dispatch function with an action like this:

dispatch({ type: 'COMPLETE_TODO', payload: { id: 2 } });

And if you want to delete a todo item, you can use the dispatch function with an action like this:

dispatch({ type: 'DELETE_TODO', payload: { id: 3 } });

By using useReducer, you can define multiple actions in one central place, and your state will be updated accordingly. This can make your code more structured and easier to understand.

Difference between useState and useReducer hook

Here is a difference between the useState and useReducer hooks.

useStateuseReducer
Use when state updates are simple and only require setting a new valueUse when state updates are complex and based on multiple actions
Updates state directly with a new valueRequires a reducer function to handle state updates
Returns a state value and a function to update the stateReturns a state value and a dispatch function to update the state
May cause unnecessary re-renders if the state is updated frequentlyAllows for optimization of performance by returning a new state object only when the state has actually changed
Can also be used for sharing state between multiple componentsUseful for sharing state between multiple components
May be simpler to use in smaller or less complex applicationsMay require more code and setup, but can be more powerful and flexible in managing state

Conclusion

Overall, useReducer can make your code more organized and easier to understand by separating your state management into smaller, more manageable pieces.