Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

110
Views
Multiple `setState` not synchronized - if one uses a value obtained from `await`

I found that, if:

  1. there are two setState
  2. the first one is called with a value obtained from await
  3. the both are called in the same thread

then, there is a frame where one state is set but the other is not.

Example:

const [bool1, setBool1] = useState(false)
const [bool2, setBool2] = useState(false)

useEffect(() => {
  (async () => {
    const _bool1 = await true
    setBool1(_bool1)
    const _bool2 = true
    setBool2(_bool2)
  })()
}, [])

console.log(`bool1: ${bool1}, bool2: ${bool2}`)

Live example (open browser console for output):

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script type="text/babel">
  const {useState, useEffect} = React;
  const App = () => {
    const [bool1, setBool1] = useState(false)
    const [bool2, setBool2] = useState(false)

    useEffect(() => {
      (async () => {
        const _bool1 = await true;
        setBool1(_bool1);
        const _bool2 = true;
        setBool2(_bool2);
      })();
    }, [])

    console.log(`bool1: ${bool1}, bool2: ${bool2}`);
    return <p>See browser console for output</p>;
  }
  
  ReactDOM.render(<App />, document.body);
</script>

The output is:

bool1: false, bool2: false
bool1: true, bool2: false
bool1: true, bool2: true

Here, the second line is confusing - I feel that there shouldn't be a frame where bool1 and bool2 don't have the same value. I know the fact that setState doesn't set a value in the same frame in general, but is that fact actually related in this case?

More confusingly, if 1. is not met, namely, if I remove await for setBool1, the second line vanishes. I don't get how the await breaks the synchronization between setBool1 and setBool2 in this case - because I think the promise is already reasolved when setBool1 is called, so it shouldn't make a difference.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

The useState hook triggers re-render. So, since it's not batched due to asynchronous state updates, when setBool1(_bool1) is executed the component re-renders with the new bool1 value and then continues with the next setBool2(_bool2) that is why you see this happening in that order:

bool1: false, bool2: false
bool1: true, bool2: false
bool1: true, bool2: true

What's Batching?

A React feature that combines all the state updates into a single update, causing a single re-render thereby improving the performance of the app. In earlier versions of React, batching was only done for the event handlers.

But!

In the case of asynchronous state updates, state updates are not batched.

Here you can find a good and extensive explanation https://blog.saeloun.com/2021/07/22/react-automatic-batching.html

More info: https://github.com/reactwg/react-18/discussions/21

This is supposed to change with React 18

Starting in React 18 with createRoot, all updates will be automatically batched, no matter where they originate from.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!