For enquiries call:

Phone

+1-469-442-0620

April flash sale-mobile

HomeBlogWeb DevelopmentPower Manage Your State Using React’s UseReducer() Hook

Power Manage Your State Using React’s UseReducer() Hook

Published
05th Sep, 2023
Views
view count loader
Read it in
8 Mins
In this article
    Power Manage Your State Using React’s UseReducer() Hook

    Keeping track of how your application data changes over time is referred to as state management in React. You will be able to create dynamic apps that adapt to user input by controlling the state of your application. In React, there are numerous techniques for handling state, including class-based state management and third-party frameworks such as Redux. In this article, you'll learn how to handle state on functional components using Hooks.

    Hooks are a group of tools that run custom functions when the props of a component change. Developers can use Hooks to produce shorter, more readable code that is easy to share and maintain because this approach of state management does not involve the use of classes. One of the primary distinctions between Hooks and class-based state management is that no single object holds all of the states. Instead, you can divide the state into parts that can be updated independently.

    If you've been working with React for a while, you're probably familiar with patterns like render props and higher-order components that attempt to tackle this. However, using these patterns requires you to restructure your components, which can be time-consuming and make code more difficult to follow.

    In React DevTools, you will most certainly encounter a "wrapper hell" of components surrounded by layers of providers, consumers, higher-order components, render props, and other abstractions. While we could filter these out in DevTools, this hints at a larger issue: React requires a better primitive for sharing stateful functionality.

    Hooks allow you to abstract stateful logic from a component so that it may be tested and reused independently. They allow you to reuse stateful code without having to change the component hierarchy. This makes it simple to distribute Hooks among several components or with the community.

    Managing state with Hooks

    Hooks are functions that allow function components to "hook into" React state and lifecycle features. Hooks do not work within classes; instead, they allow you to use React without them. (While we don't recommend rewriting your existing components overnight, you can begin using Hooks in the new ones if you like.

    Managing state in React, especially in large apps, was used to mandate the use of third-party frameworks like Redux and MobX. These third-party tools made it easier to update the state of your application in a more predictable and fine-grained manner, but they usually came with additional overhead and a high learning curve.

    React includes a few built-in Hooks, such as useState. You can even write your own Hooks to reuse stateful behavior across components. We'll start with the built-in Hooks.

    useState

    useState is a Hook that is invoked within a function component to add some local state to it. This state will be preserved between re-renders by React. useState returns a pair consisting of the current state value and a function that can be used to update it. This function can be called from an event handler or anywhere else. It's comparable to this. setState in a class, however, it does not blend the old and new states.

    const [state, setState] = useState(initialState);

    Example 1:

    Declaring a state variable: 
    
    class Demo extends React.Component { 
      constructor(props) { 
        super(props); 
        this.state = { 
    count: 0 
        }; 
    }

    We don't have this in a function component, thus we can't assign or read this.state. Instead, we invoke the useState Hook from within our component:

    import React, { useState } from 'react';
     function Demo() {
      const [count, setCount] = useState(0);
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }

    The useState function declares a "state variable." Our variable in the above example is count. This is a technique to "preserve" some values across function calls — useState is a new way to use the same capabilities in a class that this.state provides. Variables normally "disappear" when a function closes, but React preserves state variables.

    useState returns a pair of values: the current state and an update function. Because of this, we write const [count, setCount] = useState (). In a class, this is comparable to this. state.count and this.setState as a pair.

    We declare count as a state variable and set it to 0. Between re-renders, React will remember its current value and return the most recent one to our function. setCount can be used to update the current count.

    Example 2:

    function ExampleWithManyStates() {
      // Declare multiple state variables!
      const [age, setAge] = useState(21);
      const [pet, setPet] = useState('dog');
      const [todos, setTodos] = useState([{ text: 'Complete assignment' }]);
      // ...
    }

    The array destructuring technique allows us to give other names to the state variables we declared by invoking useState. The useState API does not support these names. Instead, React considers that if you call useState many times, you will do it in the same sequence on each render.

    Using the useReducer() hook

    useReducer is one of the new Hooks included with React 16.8. It is an alternative to the useState Hook that aids in the management of complex state logic in React applications. When paired with other Hooks such as useContext, useReducer can be an excellent alternative to Redux or MobX — in fact, it can be an outright better solution in some cases.

    Before we move further, I would like to state that this tutorial is not condemning Redux and MobX, which are frequently the best alternatives for managing the global state in large React apps. However, far too often, React developers rely on third-party state management frameworks when Hooks could have handled their state just as well.

    Coupled with the difficulty of getting started with a third-party library like Redux and the amount of boilerplate code required, managing state with React Hooks and the Context API is a very appealing option because there is no need to install an external package or add plenty of files and folders to manage global state in our application.

    Can you replace Redux?

    Redux is a predictable state container that allows you to create JavaScript apps that act reliably across client, server, and native environments and are simple to test.

    The state of your application is saved in a store with Redux, and any component can access any state that it requires from this store.

    One of the most common criticisms towards Redux is that it needs a lot of boilerplate code to set up some fairly simple functions. The inclusion of redux and react-redux expands the project's bundle size, while the arrangement increases the code's complexity.

    This is not due to the redux developers' fault. Redux is intended to be a universal state management tool that is not limited to React. As a result, adapting it to any particular framework will always require a little more setup than anything particularly intended for that framework.

    useReducer solves this problem as it is a react hook that provides the fundamental state management features provided by redux without all of the boilerplate code in the setup.

    This is the (nearly) appropriate alternative for projects that require a more advanced state management system but do not require the extra bells and whistles that come with redux.

    Because useReducer is specifically intended for React, it is relatively simple to incorporate into React components.

    Let’s work with useReducer()

    The useReducer, like the useState Hook, is used to save and update states. It takes as its first parameter a reducer function and as its second parameter the initial state.

    useReducer provides an array containing the current state value as well as a dispatch function to which you can pass an action and then invoke. This is similar to the Redux pattern, but with a few modifications.

    const [state, dispatch] = useReducer(reducer, initialArg, init);

    When you have complex state logic including several sub-values or when the next state is dependent on the prior one, using Reducer is usually preferable to using State. Because you may pass dispatch down instead of callbacks, useReducer allows you to enhance performance for components that generate deep modifications.

    Example: Increment a number

    import React, { useReducer } from 'react'; 
    function Counter() { 
      const [sum, dispatch] = useReducer((state, action) => { 
        return state + action; 
      }, 0);
      return ( 
        <> 
          {sum} 
          <button onClick={() => dispatch(1)}> 
            Add 1 
          </button> 
        </> 
      ); 
    }

    Power Manage Your State Using React’s UseReducer() Hook

    Power Manage Your State Using React’s UseReducer() Hook
    You can see how hitting the button causes an action with a value of 1 to be executed, which is then added to the current state, and the component to re-render with the new (bigger!) state.

    Specify the initial state

    There are two methods for initializing the useReducer state. Depending on the application, you can select either one. The most straightforward method is to pass the initial state as a second argument:

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

    React does not employ the Redux-popularized state = initialState argument convention. Because the initial value is sometimes dependent on props, it is given via the Hook call instead. If you really want to imitate the Redux behavior, you can call useReducer(reducer, undefined, reducer) but it's not recommended.

    Summary

    To recap what we’ve learnt, Hooks were a significant change in React that introduced a new mechanism to share code and update components without the use of classes.  

    You now have the capabilities to develop complicated projects that respond to users and dynamic data since you can create components using useState and useReducer. You also have a solid base of knowledge from which to investigate more advanced Hooks or design custom Hooks.

    Profile

    Abhresh Sugandhi

    Author

    Abhresh is specialized as a corporate trainer, He has a decade of experience in technical training blended with virtual webinars and instructor-led session created courses, tutorials, and articles for organizations. He is also the founder of Nikasio.com, which offers multiple services in technical training, project consulting, content development, etc.

    Share This Article
    Ready to Master the Skills that Drive Your Career?

    Avail your free 1:1 mentorship session.

    Select
    Your Message (Optional)

    Upcoming Web Development Batches & Dates

    NameDateFeeKnow more
    Course advisor icon
    Course Advisor
    Whatsapp/Chat icon