DEV Community

Ibrahim Aziz
Ibrahim Aziz

Posted on

From useState to useReducer: Level Up Your State Management in React

Welcome to an exciting journey into the world of React's useReducer hook! In this sequel to our previous article, we'll explore how useReducer empowers us to manage state more efficiently in React applications.

Get ready for a rewarding adventure as we delve into the remarkable capabilities of the useReducer hook. Let's uncover its secrets and discover how it simplifies state management in React! ๐Ÿš€

React gif

๐ŸŽฃ React's useReducer hook is a powerful tool that enables us to handle complex state logic in our applications. Unlike the more commonly used useState hook, useReducer is especially useful when managing state transitions that involve intricate data or multiple pieces of information.In this article, we'll explore the useReducer hook, its syntax, and provide a real-life scenario to demonstrate its benefits.

Understanding the useReducer hook

The useReducer hook is a function provided by React that allows us to handle state updates using a reducer function. A reducer function is basically a pure function that takes the current state and an action as arguments and returns a new state. It follows a well-defined pattern:


function reducer(state, action) {
  switch (action.type) {
    case 'ACTION_TYPE_1':
      // return updated state for ACTION_TYPE_1
      break;
    case 'ACTION_TYPE_2':
      // return updated state for ACTION_TYPE_2
      break;
    // Additional cases for other action types
    default:
      return state;
  }
}
Enter fullscreen mode Exit fullscreen mode

Syntax of the useReducer Hook:

Let's explore the syntax of the useReducer hook.The useReducer hook takes two arguments: the reducer function and the initial state. It returns an array with two elements: the current state and a dispatch function to trigger state updates.

const [state, dispatch] = useReducer(reducer, initialState);
Enter fullscreen mode Exit fullscreen mode

Scenario: Managing a Todo List with useReducer

To better understand the useReducer hook, let's consider a simple scenario where we need to manage a todo list with the ability to add and remove tasks.

todolist

Step 1: Define the Reducer Function:

const todoReducer = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, { id: Date.now(), text: action.payload, completed: false }];
    case 'REMOVE_TODO':
      return state.filter((todo) => todo.id !== action.payload);
    default:
      return state;
  }
};
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Todo Component

import React, { useReducer, useState } from 'react';

const Todo = () => {
  const [todos, dispatch] = useReducer(todoReducer, []);
  const [newTodoText, setNewTodoText] = useState('');

  const handleAddTodo = () => {
    if (newTodoText.trim() !== '') {
      dispatch({ type: 'ADD_TODO', payload: newTodoText });
      setNewTodoText('');
    }
  };

  const handleRemoveTodo = (id) => {
    dispatch({ type: 'REMOVE_TODO', payload: id });
  };

  return (
    <div>
      <input
        type="text"
        value={newTodoText}
        onChange={(e) => setNewTodoText(e.target.value)}
      />
      <button onClick={handleAddTodo}>Add Todo</button>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => handleRemoveTodo(todo.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

Code Explanation:

In this scenario, we define a todoReducer function that handles two types of actions: ADD_TODO and REMOVE_TODO. The ADD_TODO action adds a new todo item to the state, while the REMOVE_TODO action removes a todo item based on its ID.

The Todo component uses the useReducer hook to manage the todo list state, initializing it with an empty array as the initial state. It also uses the useState hook to manage the input for adding new todo items.

When the "Add Todo" button is clicked, the handleAddTodo function is called, which dispatches the ADD_TODO action with the new todo's text. The reducer then updates the state with the new todo.

Similarly, when the "Remove" button is clicked for a todo item, the handleRemoveTodo function dispatches the REMOVE_TODO action with the todo's ID to remove it from the state.

todolist-demo

Conclusion

๐ŸŽ‰ The useReducer hook is a powerful tool for managing complex state logic in React applications. By using a reducer function to handle state updates, we can achieve a clear and predictable flow of data. The example scenario of managing a todo list demonstrates how useReducer simplifies state management and keeps our code clean and maintainable.

๐Ÿš€ So, let your creativity soar as you centralize state transitions with the elegant reducer function. Say goodbye to tangled state management woes and welcome a cleaner, more maintainable codebase. By incorporating useReducer, you'll wield the ability to build complex state logic with ease, unleashing your full potential as a React maestro.

๐Ÿ”ฅ Remember, the journey to becoming a React virtuoso is about continuous learning and exploration. So go forth with confidence, fuel your passion for coding, and let your projects soar to new heights!

Happy coding, and may the useReducer magic guide you to React brilliance! ๐ŸŒŸ

happy coding

๐Ÿ“ข Have you used the useReducer hook in your React projects? Share your experiences and favorite use cases in the comments below! ๐Ÿ’ฌ

Ziz Here๐Ÿš€
Kindly Like, Share and follow us for more contents related to web development.

Top comments (10)

Collapse
 
brense profile image
Rense Bakker

You don't even need to use switch statements in your reducer. At it's core the dispatcher just let's you apply some new value to existing state in the reducer function:

const initialPersonState = {
  firstName: 'John'
}

function simpleReducer(currentState, nextState) {
  return { ...currentState, ...nextState }
}

function SomeComponent(){
  const [person, setPerson] = useReducer(simpleReducer, initialPersonState)

  const handleChangePerson = useCallback(() => {
    setPerson({ lastName: 'Doe' })
  }, [])

  return // ...
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ibrahzizo360 profile image
Ibrahim Aziz

Thank you for sharing your insights! I appreciate your approach to using the spread operator for state updates within the reducer. It's indeed a concise way to achieve state transitions.

Collapse
 
qbentil profile image
Bentil Shadrack

Awesome insight here๐Ÿ™Œ

Collapse
 
ibrahzizo360 profile image
Ibrahim Aziz

Thank you so much for your kind words! I'm thrilled that you found the article insightful.

Collapse
 
cod_maxx profile image
Maxx_Cod

Great one boss๐Ÿ‘โ™ฅ๏ธ

Collapse
 
ibrahzizo360 profile image
Ibrahim Aziz

Thank you for your kind words! I'm glad you enjoyed the article.

Collapse
 
tphilus profile image
Theophilus K. Dadzie

I love it Bro

Collapse
 
ibrahzizo360 profile image
Ibrahim Aziz

Thank you! Really appreciate your positive feedback.๐Ÿ˜Š

Collapse
 
gyauelvis profile image
Gyau Boahen Elvis

Good work

Collapse
 
ibrahzizo360 profile image
Ibrahim Aziz

Thank you very much boss!๐Ÿ™Œ๐Ÿ˜Š