Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useState hook, setState function. Accessing previous state value

Tags:

Are these two equivalent? If not which is best and why?

const [count, setCount] = useState(initialCount);
<button onClick={() => setCount(count + 1)}>+</button>
const [count, setCount] = useState(initialCount);
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
like image 475
Laurie Poulter Avatar asked Jun 01 '19 07:06

Laurie Poulter


People also ask

How do you get the previous state value in React Hooks?

With React class components you have the componentDidUpdate method which receives previous props and state as arguments or you can update an instance variable (this. previous = value) and reference it later to get the previous value.

How do you update state with previous state using useState hook?

const [state, setState] = useState(initialState); To update the state, call the state updater function with the new state setState(newState) . Alternatively, if you need to update the state based on the previous state, supply a callback function setState(prevState => newState) .

Can I pass a function in useState hook?

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.


1 Answers

If the next state value depends on the previous value, as in this example of an increment button, it's better to use the functional version of setState (setCount(prevCount => prevCount + 1)).

You can run into errors if you're passing the setter function into a callback function, like an onChange or HTTP Request response handler.

As an explicit example, in the below page, if you click "Delayed Counter (basic)" and then click "Immediate Counter", the count will only increment by 1. However, if you click "Delayed Counter (functional)", followed by "Immediate Counter", the count will eventually increment by 2.

import React, { useState } from "react";
import ReactDOM from "react-dom";

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

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setTimeout(() => setCount(count + 1), 2000)}>
        Delayed Counter (basic)
      </button>
      <button onClick={() => setTimeout(() => setCount(x => x + 1), 2000)}>
        Delayed Counter (functional)
      </button>
      <button onClick={() => setCount(count + 1)}>Immediate Counter</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Counter />, rootElement);
like image 68
Edward D'Souza Avatar answered Sep 20 '22 15:09

Edward D'Souza