In ReactJS, why does `setState` behave differently when called synchronously?

Here’s what’s happening.

Synchronous

  • you press X
  • input.value is ‘HelXlo’
  • you call setState({value: 'HelXlo'})
  • the virtual dom says the input value should be ‘HelXlo’
  • input.value is ‘HelXlo’
    • no action taken

Asynchronous

  • you press X
  • input.value is ‘HelXlo’
  • you do nothing
  • the virtual DOM says the input value should be ‘Hello’
    • react makes input.value ‘Hello’.

Later on…

  • you setState({value: 'HelXlo'})
  • the virtual DOM says the input value should be ‘HelXlo’
    • react makes input.value ‘HelXlo’
    • the browser jumps the cursor to the end (it’s a side effect of setting .value)

Magic?

Yes, there’s a bit of magic here. React calls render synchronously after your event handler. This is necessary to avoid flickers.

Leave a Comment