1

What difference between direct argument and callback in setState?
I've heard that the react scheduler only correctly exposes component updates when a callback is used. So that they hit the tick 16ms

const [state, setState] = useState(null)

function handle() { 
   setState(true)
   // or
   setState(() => true)
 }

popuguy
  • 39
  • 6

1 Answers1

3

Using the callback form allows you to use the previous value in state, even if the previous value hasn't been rendered yet. For example:

const [counter, setCounter] = useState(0);

const someHandler = () => {
  setCounter(counter + 1);
  setCounter(counter + 1);
}

will only end up increasing counter by one, because the counter that's in scope when the handler runs is from a single render. It's like doing setCounter(1); setCounter(1), so counter ends up being 1, not 2.

Using the callback form allows you to use the previous state:

setCounter(counter => counter + 1);
setCounter(counter => counter + 1);

will properly increase counter by 2, not just 1.

Another difference is that using the callback form allows you to put functions into state:

const [fn, setFn] = useState();
const fnToPutInState = () => {
  console.log('fn');
};

// ...

setFn(fnToPutInState);

will result in the function being invoked immediately, rather than setting state. The solution is to return the function from a callback instead:

setFn(() => fnToPutInState);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • The callback also allows you to avoid loops when using `useEffect` to update state based on the current value in the state i.e. the dependency array when using the callback is just `[setFn]` where if you were trying to use direct argument you would need `[value, setFn]` to also have access to the current value. – Jacob Smit Oct 14 '20 at 21:04
  • Thank you for answer. I know about batching updates. I'm interested in more depth, as an example with the work of the react scheduler – popuguy Oct 14 '20 at 21:14