How to Update useState Hook in React

Updating state is a core concept in React when building dynamic user interfaces. This guide provides a straightforward explanation of how to use the useState hook to update state in React functional components. You will learn the syntax for basic state updates, how to safely update state based on a previous value using functional updates, and the correct way to modify complex state structures like objects and arrays.

Basic State Updates

To update state in React, you call the dispatch function returned by the useState hook. This function accepts a new value and schedules a re-render of the component with the updated state.

import React, { useState } from 'react';

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

  return (
    <button onClick={() => setCount(10)}>
      Set Count to 10
    </button>
  );
}

Updating State Based on Previous State

When your new state depends on the previous state, you should pass a callback function to the state setter instead of a direct value. This prevents bugs caused by React’s asynchronous state batching. The callback receives the pending state as its argument.

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

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

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

Updating Objects in State

In React, state should be treated as immutable. When updating an object, you must copy the existing object using the spread operator (...) and then overwrite the specific properties you want to change. Failing to copy the object will prevent React from detecting the change and triggering a re-render.

const [user, setUser] = useState({ name: 'Alex', age: 30 });

const updateAge = () => {
  setUser(prevUser => ({
    ...prevUser,
    age: 31
  }));
};

Updating Arrays in State

Similar to objects, arrays in React state must not be mutated directly using methods like push() or splice(). Instead, use non-mutating array methods like the spread operator, map(), filter(), or concat() to return a new array.

Adding an item to an array:

const [items, setItems] = useState(['Apple', 'Banana']);

const addItem = () => {
  setItems(prevItems => [...prevItems, 'Orange']);
};

Filtering an item from an array:

const [items, setItems] = useState(['Apple', 'Banana', 'Orange']);

const removeItem = (itemToRemove) => {
  setItems(prevItems => prevItems.filter(item => item !== itemToRemove));
};