paint-brush
Migrating from useState to useReducer in React Hooksby@lyndsiwilliams
5,782 reads
5,782 reads

Migrating from useState to useReducer in React Hooks

by Lyndsi WilliamsJune 22nd, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

`useState' and `useReducer` are both React hooks that allow you to manage state in your components. `useState` is a simpler hook that allows you to managing a single piece of state, while `useReducer` is more powerful. Here is a basic example of how to convert a component that uses `useState` to manage a single piece of state.
featured image - Migrating from useState to useReducer in React Hooks
Lyndsi Williams HackerNoon profile picture


useState and useReducer are both React hooks that allow you to manage the state of your components. useState is a simpler hook that allows you to manage a single piece of state, while useReducer is more powerful and allows you to manage more complex states that may have multiple values and require more sophisticated updates.


To convert from useState to useReducer, you can follow these general steps:


  1. Define an initial state and an action type.
  2. Replace the useState hook with the useReducer hook.
  3. Create a reducer function that takes a state and an action and returns a new state.
  4. Update the component to use the new state and dispatch functions returned by the useReducer hook, which should have the reducer and initial state passed in.


Here is a basic example of how to convert a component that uses useState to manage a single piece of state.


Start with a Counter component:

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </>
  );
}

export default Counter;


To convert this to use useReducer, we can follow the steps outlined above:


  1. Define an initial state and an action type:

    const initialState = { count: 0 };
    const INCREMENT = 'increment';
    


  2. Replace the useState hook with a useReducer hook:

    import React, { useReducer } from 'react';
    
    const Counter = () => {
      const [state, dispatch] = useReducer(reducer, initialState);
    
      // ...
    }
    


  3. Create a reducer function that takes a state and an action and returns a new state:

    const reducer = (state, action) => {
      switch (action.type) {
        case INCREMENT:
          return { count: state.count + 1 };
        default:
          throw new Error();
      }
    }
    


  4. Update the component to use the new state and dispatch functions returned by the useReducer hook, which should have the reducer and initial state passed in:

    const Counter = () => {
      const [state, dispatch] = useReducer(reducer, initialState);
    
      const increment = () => {
        dispatch({ type: INCREMENT });
      };
    
      return (
        <>
          <p>Count: {state.count}</p>
          <button onClick={increment}>Increment</button>
        </>
      );
    }
    


In step 4, the dispatch function is used to send an action to the reducer function. The reducer function then returns a new state based on the action type. The component is also updated to use state.count instead of the count variable previously returned by useState.


In this simple example, useReducer doesn't bring many benefits over useState. But in general, as your components grow in complexity, useReducer provides a more powerful and flexible way to manage state - especially when you have a more complex state that requires multiple values and more sophisticated updates.


This article was originally posted here.

Let me know what you think in the comments!