Home > database >  why the normal counter runs only last setCount argument and functional counter runs all setCount?
why the normal counter runs only last setCount argument and functional counter runs all setCount?

Time:03-02

Why the first one is only running the last setCount argument and when we are using the arrow function for setCount it's running both the argument.

eg: if you click the Normal button the count will be 5 as it should be 9
If you click the Functional button the count will be 2 as it is running both the SetCount

import react, { useState, useEffect } from "react";

export default function App() {
 const [count, setCount] = useState(0);
 console.log(count);
 return (
   <div className="App">
     <button
       onClick={() => {
         setCount(count   1);
         setCount(count   3);
         setCount(count   5);
       }}
     >
       Normal
     </button>
     <br />

     <button
       onClick={() => {
         setCount((c) => c   1);
         setCount((c) => c   1);
       }}
     >
       Functional
     </button>
   </div>
 );
}

CodePudding user response:

when we use parameter set value once

current value set on the count and run 3 methods with parameters

setCount(count   1);
setCount(count   3);
setCount(count   5);

but in this case : setCount((c) => c 1); when (c) => c 1 method called c get the current value each time

CodePudding user response:

Your "normal" code captures the current state value of count in a closure. The first time your component is rendered this basically boils donw to following:

() => {
    setCount(0   1);
    setCount(0   3);
    setCount(0   5);
}

As state updates are batched the last one wins, so the resulting state value is 5.

The "Functional" code sample uses the callback Dispatch, that provides you with the previous value of state at the time your change happens, not affected by closures. Basically:

() => {
    setCount((0) => 0   1);
    setCount((1) => 1   1);
}

Both have their uses, depends on what you want.

CodePudding user response:

When computing the sum of values, in your case, calculating 9 from the sum of 1, 3 and 5, we need pass a function to setCount with the parameter being the previous value

setCount((c) => c   1); // previous count is 0, new count is 1
setCount((c) => c   3); // previous count is 1, new count is 4
setCount((c) => c   5); // previous count is 5, new count is 9

This is documented in official doccs:

https://reactjs.org/docs/hooks-reference.html#functional-updates

If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.

  • Related