Automatic Batching and startTransition

REACT

Muhammad Faheem Akhtar

Developer?

@mfaheemakhtar [twitter, github]

faheem.dev

Automatic Batching

more batching by default

What is Batching?

Multiple state updates in a single re-render.

Benefits?

  • avoids unnecessary re-renders
  • prevents half-finished renders

Already does that

But only in event handles.

 

Not promises, setTimeouts, event handles, etc

Code

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); 	// Does not re-render yet
    setFlag(f => !f); 		// Does not re-render yet
    // React will only re-render once at the end (that's batching!)
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

Demo

Does not

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 17 and earlier does NOT batch these because
      // they run *after* the event in a callback, not *during* it
      setCount(c => c + 1); // Causes a re-render
      setFlag(f => !f); 	// Causes a re-render
    });
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

Demo

What if I don't want batching?

ReactDOM.flushSync()

import { flushSync } from 'react-dom'; // Note: react-dom, not react

function handleClick() {
  flushSync(() => {
    setCounter(c => c + 1);
  });
  // React has updated the DOM by now
  flushSync(() => {
    setFlag(f => !f);
  });
  // React has updated the DOM by now
}

startTransition

deferring non-critical updates

startTransition?

defer rendering/updates

startTransition?

Urgent updates reflect direct interaction, like typing, clicking, pressing, and so on.
 

Transition updates transition the UI from one view to another.

 

Demo

Resources

https://github.com/reactwg/react-18/discussions/41

 

https://github.com/reactwg/react-18/discussions/65

 

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

 

https://reactjs.org/docs/concurrent-mode-patterns.html

Made with Slides.com