Search code examples
javascriptparameters

() => count + 2 vs. (count) => count + 2


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

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

What I don’t understand in this function is,

setCalculation(() => count * 2); setCount((c) => c + 1);

They do the similar work, but why does the first line NOT have the parameter? Does this make any difference between two lines?

And also why does it use ‘c’, not ‘count’? (While ‘count’ was used in the earlier line.)

Thank you.

I thought they do the same work but I’m not sure now


Solution

  • The two have a subtle difference in where the current value of count comes from.

    When you write

    setState(() => count*2)
    // or
    setState(count * 2)
    

    The count value is captured from the current render into a closure. The main implication is that using the count value to update state does not guarantee that you have the latest.

    This matters in cases where setters might run out of order such as async operations, concurrent renders, etc.

    The simplest demonstration of the difference is by doing multiple calls together:

    // Assume count is initially 5
    setState(count * 2) // count is 10
    setState(count * 2) // count is _still_ 10, because the `count` variable is still 5
    

    Versus:

    // Assume count is initially 5
    setState(count => count * 2) // count is 10
    setState(count => count * 2) // count is 20
    

    The callback format guarantees that you get the latest value.

    As a recommendation, whenever your new state depends on the old state, access it via callback.