title: Why does each state hook update cause a separate re-render in asynchronous code?
body: <p>There are two <code>useState</code> hooks used in a component. If we allow for the event loop to &quot;reflow&quot; before modifying the state, each hook causes a separate re-render.</p>
  <pre><code>const sleep = (ms) =&gt; new Promise((resolve) =&gt; setTimeout(resolve, ms));
  
  export default function App() {
    const [foo, setFoo] = useState(&quot;initial_foo&quot;);
    const [bar, setBar] = useState(&quot;initial_bar&quot;);
  
    const onAction = useCallback(async () =&gt; {
        await sleep(0); // this is the culprit
        setFoo(&quot;updated_foo&quot;);
        setBar(&quot;updated_bar&quot;);
    }, []);
  
    console.log(`rendering foo:${foo} bar:${bar}`);
  
    return (
      &lt;&gt;
        &lt;button onClick={onAction}&gt;run test&lt;/button&gt;
        &lt;div&gt;{&quot;foo: &quot; + foo}&lt;/div&gt;
        &lt;div&gt;{&quot;bar: &quot; + bar}&lt;/div&gt;
      &lt;/&gt;
    );
  }
  </code></pre>
  <p><em>console output with <code>await sleep(0)</code>:</em></p>
  <pre><code>rendering foo:initial_foo bar:initial_bar
  rendering foo:updated_foo bar:initial_bar
  rendering foo:updated_foo bar:updated_bar
  </code></pre>
  <p>If we remove <code>await sleep(0);</code>, everything works as expected: <code>setFoo</code> and <code>setBar</code> cause a single re-render.</p>
  <p><em>console output without <code>await sleep(0)</code>:</em></p>
  <pre><code>rendering foo:initial_foo bar:initial_bar
  rendering foo:updated_foo bar:updated_bar
  </code></pre>
  <p><a href="https://codesandbox.io/s/soextrarerenderswithsleep-3o2g1" rel="nofollow noreferrer"><strong>The demo</strong></a> <em>(in the demo console output is duplicated, because it has React strict mode on)</em></p>
  <ul>
  <li>Why is it happening?</li>
  <li>Is it a bug or a feature?</li>
  <li>How can we prevent intermediate re-renders of this kind?</li>
  </ul>
  <p><em>Update:</em></p>
  <p>Issue has been created in the <a href="https://github.com/facebook/react/issues/19738" rel="nofollow noreferrer">React project repo</a></p>