For objects you can use the spread operator to use prevState within your setState call.

const [object, setObject] = useState({
  firstKey: '',
  secondKey: '',
});

setObject((prevState) => ({
  ...prevState,
  secondKey: 'value',
}));

// object = {
//   firstKey: '',
//   secondKey: 'value',
// }

The snippet below show an example of using prevState for setting the state of an object.

const {useState} = React;

const Example = ({title}) => {
  const initialState = {
    firstKey: 'empty',
    secondKey: 'empty',
    thirdKey: 'not empty',
  }
  const [object, setObject] = useState(initialState);
  
  const withPrevState = () => {
    setObject((prevState) => ({
      ...prevState,
      secondKey: 'not empty',
    }));
  }

  return (
    <div>
      <h5>Updates Second key to 'not empty'</h5>
      <p>First key: {object.firstKey}</p>
      <p>Second key: {object.secondKey}</p>
      <p>Third key: {object.thirdKey}</p>
      <button onClick={withPrevState}>
        Update with prevState
      </button>
      <button onClick={() => {setObject({secondKey: 'not empty'})}}>
        Update without prevState
      </button>
      <button onClick={() => {setObject(initialState)}}>
        Reset
      </button>
    </div>
  );
};

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Answer from ppak10 on Stack Overflow
Top answer
1 of 8
171

For objects you can use the spread operator to use prevState within your setState call.

const [object, setObject] = useState({
  firstKey: '',
  secondKey: '',
});

setObject((prevState) => ({
  ...prevState,
  secondKey: 'value',
}));

// object = {
//   firstKey: '',
//   secondKey: 'value',
// }

The snippet below show an example of using prevState for setting the state of an object.

const {useState} = React;

const Example = ({title}) => {
  const initialState = {
    firstKey: 'empty',
    secondKey: 'empty',
    thirdKey: 'not empty',
  }
  const [object, setObject] = useState(initialState);
  
  const withPrevState = () => {
    setObject((prevState) => ({
      ...prevState,
      secondKey: 'not empty',
    }));
  }

  return (
    <div>
      <h5>Updates Second key to 'not empty'</h5>
      <p>First key: {object.firstKey}</p>
      <p>Second key: {object.secondKey}</p>
      <p>Third key: {object.thirdKey}</p>
      <button onClick={withPrevState}>
        Update with prevState
      </button>
      <button onClick={() => {setObject({secondKey: 'not empty'})}}>
        Update without prevState
      </button>
      <button onClick={() => {setObject(initialState)}}>
        Reset
      </button>
    </div>
  );
};

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

2 of 8
30

In order to use Maps, you'll need to clone it before manipulating the values. Otherwise, it's mutating the original Map and React doesn't handle mutatable state.

const handleChange = useCallback(({ target: { name, checked } }) => {
  setCheckbox(prevState => {
    return new Map(prevState).set(name, checked);
  });
}, []);

Updated Working Example:

🌐
React
react.dev › reference › react › useState
useState – React
Call useState at the top level of your component to declare a state variable.
People also ask

How to Update State Based on Previous State?
To update the state based on the previous state in React, use the functional update form of the setter function provided by useState. This guarantees that you're working with the most recent state value.
🌐
dhiwise.com
dhiwise.com › post › best-practices-for-preservingprevious-state-in-react-usestate
Mastering React's useState: Handling Previous State
The Role of useEffect in Tracking State Changes
The useEffect hook can be used with useState to perform side effects in response to state changes. It can also be used to track previous state values by using refs.
🌐
dhiwise.com
dhiwise.com › post › best-practices-for-preservingprevious-state-in-react-usestate
Mastering React's useState: Handling Previous State
🌐
Medium
abidemi-dev.medium.com › react-hooks-usestate-with-previous-state-55b6272f1473
React Hooks: useState with previous state | by Abidemi Animashaun | Medium
August 10, 2021 - First, we created a counter functional component, next we used the useState Hook to create a state variable and the corresponding setter function. In the JSX, we added the three buttons to increment, decrement and reset the count value. For the increment button, onclick is an arrow function, call setCount passing in initialCount + 1 as the argument.
🌐
Reddit
reddit.com › r/reactjs › need some clarification when to use prevstate in usestate hook
r/reactjs on Reddit: Need some clarification when to use prevState in useState hook
November 9, 2020 -

Might be silly question, but I want to be sure I understand this. Example of incorrectly updating state using useState hook

I'm wondering if in this part of Todo tutorial state was updated incorrectly?

const submitTodoHandler = (e) => {
    e.preventDefault();
    setTodos([
      ...todos,
      { text: inputText, completed: false, id: Math.random() * 1000 },
    ]);
  };

Or should it be like this:

  const submitTodoHandler = (e) => {
    e.preventDefault();
    setTodos((prevTodos) => [
      ...prevTodos,
      { text: inputText, completed: false, id: Math.random() * 1000 },
    ]);
  };

If you need see whole code, I uploaded it on Github - here

Which one is it?

🌐
React
legacy.reactjs.org › docs › hooks-reference.html
Hooks API Reference – React
const [state, setState] = useState({}); setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; }); Another option is useReducer, which is more suited for managing state objects that contain multiple sub-values. The initialState argument is the state used during the initial render.
🌐
DhiWise
dhiwise.com › post › best-practices-for-preservingprevious-state-in-react-usestate
Mastering React's useState: Handling Previous State
August 5, 2024 - The useState hook is used by calling it with the initial state value and destructuring the returned array into a state variable and its setter function.
Find elsewhere
🌐
Ogzhanolguncu
ogzhanolguncu.com › blog › how-does-prevstate-works-under-the-hood
How does prevState in React work under the hood? | Oğuzhan Olguncu
February 21, 2022 - We have always been told to use prevState when dealing with useState but not really why we need it in the first place. Today, we will deep dive and see how it works under the hood to retrieve the latest state without the need of render cycle - render cycle refers to VDOM updates, not actual ...
🌐
Greenroots
blog.greenroots.info › react-hook-usestate-lazy-initialization-previous-state
ReactJS useState Hook - lazy initialization and previous state
February 17, 2022 - With the useState hook, you can pass a function as an argument to initialize the state lazily. As discussed, the initial value is needed only once at the first render.
🌐
Clue Mediator
cluemediator.com › usestate-with-the-previous-state-in-react-hooks
useState with the previous state in React Hooks - Clue Mediator
September 3, 2020 - // handle button click event to add 5 in counter const handleAddFiveClick = () => { for (let i = 0; i < 5; i++) { setCounter(prevState => prevState + 1); } } Combine all code together and see how it looks. HookCounter.js · import React, { useState } from "react"; const HookCounter = () => { const [counter, setCounter] = useState(0); // handle button click event const handleClick = () => { setCounter(counter + 1); } // handle button click event to add 5 in counter const handleAddFiveClick = () => { for (let i = 0; i < 5; i++) { setCounter(prevState => prevState + 1); } } return <div> <b>Counte
🌐
Valentino G.
valentinog.com › blog › react-object-is
Demystifying Object.is and prevState in React useState
April 15, 2021 - The following example shows a slightly "larger" state, and a state updater function which makes use of prevState: import { useState } from "react"; export default function MyComponent() { const [person, setPerson] = useState({ name: "Jules", age: 33, city: "Malaga" }); function changeName() { setPerson((prevState) => { return { ...prevState, name: "Chris" }; }); } return ( <div> <h1>Hello {person.name}</h1> <h2>You are from {person.city}</h2> <button onClick={changeName}>CHANGE NAME</button> </div> ); }
🌐
LogRocket
blog.logrocket.com › home › how to access previous props or state with react hooks
How to access previous props or state with React Hooks - LogRocket Blog
June 4, 2024 - In this example, even if the props changes, the count won’t. The reason for this is that despite the component re-rendering as a result of the props change, useState doesn’t re-render. The best way to fix this would be to move useState into the parent component and then pass count as a props.
🌐
DEV Community
dev.to › vvkkumar06 › create-a-modified-usestate-hook-to-get-previous-value-53mk
Create a modified useState hook to get previous value - DEV Community
December 27, 2023 - Whenever there is a change in the state, we will also update prevState. import { useEffect, useRef, useState } from "react"; const useStateModified = (initalState) => { const [state, setState] = useState(initalState); const prevState = useRef(initalState); useEffect(() => { prevState.current = state; }, [state]); return [state, setState, prevState.current]; }; export default useStateModified;
Top answer
1 of 3
11

First of all, you can see the official explanation here.

In this case, I somehow access the previous count value.

You are not somehow accessing the previous count value. If you use a functional update and give a callback function to the setter, it returns the previous state to you and you use this value in your callback function.

setCount expects now a function

Since you provide a function, it can use it.

setCount is now run asynchron

Actually, no. It is not an asynchronous function. It just provides the previous state and you use it. State setters are not asynchronous, state update is.

Where is this function coming from?

Where is prevCount coming from?

Already answered.

When i run this, what is put into prevCount?

You provide what do you want to be set the new state there. In your example, you want to increment count by 1, so you are providing + 1

Here is a naive explanation for this logic. Just a naive one. I'm adding this to exemplify the callback logic, this is not related to React's setState.

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    return val(state);
  }

  return val;
}

const stateWithFunctionalUpdate = setState(prev => prev + 1);
const stateWithNormalUpdate = setState(9);
console.log(stateWithFunctionalUpdate);
console.log(stateWithNormalUpdate);

Maybe this example would be suitable for mimicking the React's state setting logic. Again, just a naive approach.

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    state = val(state);
  } else {
    state = val;
  }

}

setState(9);
setState(prev => prev + 1);

console.log("state", state);

Let's look at the real implementation of useState (without typings):

export function useState(initialState) {
  return useReducer(
    basicStateReducer,
    // useReducer has a special case to support lazy useState initializers
    initialState
  );
}

Well, it just uses useReducer behind the curtains. It sets the initial state and uses basicStateReducer which is:

function basicStateReducer(state, action) {
  return typeof action === "function" ? action(state) : action;
}

Like our naive approach, it looks for the type of the action and behaves according to that. Finally, this is what useReducer returns:

return [workInProgressHook.memoizedState, dispatch];

So, at the end of the day, if we provide a function to useState, it takes it and then run it on our state and returns the value back.

2 of 3
2

Here is my opinion how i understand:

In this case, I somehow access the previous count value. -> setCount will check param, if the param is a callback it will call that call back and pass previous state for param. Result of call back will be next state.

setCount expects now a function -> yes, function handle you logic and return next state.

setCount is now run asynchron -> this function is synchron but after it return result. The hook for setCount will dispatch event to update the next state

Where is this function coming from? -> your can do anything in function as long as param will be current state and return a next state.

Where is prevCount coming from? -> will be passed when call setCount(it's get from current state).

When i run this, what is put into prevCount? -> current state of setCount.

=> Example for how to pass a value or a call back to setCount here: useState hook, setState function. Accessing previous state value

🌐
Medium
medium.com › @nagireddygajjela19 › 3-react-hooks-tutorial-usestate-with-previous-state-3647b25050eb
3. React Hooks Tutorial - useState with previous state | by NagiReddy Gajjela | Medium
October 21, 2023 - In this blog post, we delved into a more advanced example of state management in React using the useState hook. We created a counter component with buttons to increment, decrement, and reset the count value, and we emphasized the importance of updating state based on the previous state value.
🌐
Dave Ceddia
daveceddia.com › usestate-hook-examples
4 Examples of the useState Hook
July 12, 2020 - import React, { useState } from 'react'; function StepTracker() { const [steps, setSteps] = useState(0); function increment() { setSteps(prevState => prevState + 1); } return ( <div> Today you've taken {steps} steps!
🌐
Medium
medium.com › geekculture › using-prevstate-with-react-basic-and-complex-f7f8ab4ce1b6
Using prevState with React, basic and complex | by AntoineGGG | Geek Culture | Medium
July 16, 2023 - How to use the famous “prevState” to modify our React state without overriding it ! ... import "./App.css"; import React, { useState } from "react"; const App = () => { const [mySuperCounter, setMySuperCounter] = useState(0); const handleIncrement = () => { setMySuperCounter(mySuperCounter + 1); setMySuperCounter(mySuperCounter + 1); setMySuperCounter(mySuperCounter + 1); }; const handleReset = () => { setMySuperCounter(0); }; return ( <div className="App"> <div> <button className="super-button" type="submit" onClick={handleIncrement}> Incrementor </button> <button className="super-button" type="submit" onClick= {handleReset}> State Resettor </button> </div> <div>{mySuperCounter}</div> </div> ); }; export default App;
🌐
strobecorp
strobecorp.com › home › reactjs – prevstate in the new usestate react hook?
ReactJS - prevState in the new useState React hook?
February 28, 2024 - You may use “prevState” to ensure that your state changes are based on the most recent state when you update a state using the setState method made available by the useState hook.
🌐
Delft Stack
delftstack.com › home › howto › react › react setstate prevstate
setState and prevState in React | Delft Stack
December 21, 2022 - Let’s correct our other buttons as well using prevState. Counter.js will look like below. # react import React from "react"; function Counter() { const initialNum = 0; const [num, setNum] = React.useState(initialNum); const IncrementByFive = () => { for (let i = 0; i < 5; i++) { setNum((prevNum) => prevNum + 1); } }; return ( <div> <p>Counter: {num}</p> <button onClick={() => setNum(initialNum)}>Reset</button> <button onClick={() => setNum((prevNum) => prevNum + 1)}> Increment </button> <button onClick={() => setNum((prevNum) => prevNum - 1)}> Decrement </button> <button onClick={IncrementByFive}>Increment By 5</button> </div> ); } export default Counter; So, in this guide, we learned about the issues which can be resolved using prevState, and we also built a basic counter app in React using setState and prevState.
🌐
DevYoma
devyoma.hashnode.dev › using-react-setstate-with-prevstate
Using React setState() with prevState - DevYoma - Hashnode
February 10, 2024 - A better way of using the useState() hook with the prevState in React JS ⚛