React 18 features : Batching, Transitions, and Suspense

  • Automating Batching: flushSync (Automating Batching) — wait for a micro-task to finish before re-rendering, to opt out from rendering
  • Transition: React.startTransition — Not urgent resources for updating, useTransition Hook — have isPending, startTransition
  • support for <Suspense …/> on the server
  • Strict mode for React

Upgrade to React 18

// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(<App tab="home" />, container);
// After
import ReactDOM from 'react-dom';
import App from 'App';

const container = document.getElementById('app');

// create a root
const root = ReactDOM.createRoot(container);

//render app to root
root.render(<App />);

Automatic Batching

  • React batched state updates in event handlers, However, state updates that happened outside of event handlers were not batched.
// Before React 18 only React events were batchedconst handleClick = () => {
setCounter();
setActive();
setValue();
} //re-rendered once at the end.
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
}
fetch('/network').then( () => {
setCounter(); //re-rendered 1 times
setActive(); //re-rendered 2 times
setValue(); //re-rendered 3 times
});

//Total 3 re-renders
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
}, 1000);
// React will render twice, once for each state update (no batching)

- React 18 introduces automatic batching which allows all state updates — even within promises, setTimeouts, and event callbacks — to be batched.

- React will wait for a micro-task to finish before re-rendering.

// After React 18 updates inside of timeouts, promises,
// native event handlers or any other event are batched.

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

setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
}, 1000);

If you want to opt-out you can use flushSync,

import { flushSync } from 'react-dom';

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
}

Transitions

  • Transitions can be used to mark UI updates that do not need urgent resources for updating.
  • You can mark updates as non-urgent by using startTransition. Here is an example of what a typeahead component would like when marked with transitions:

React.startTransition(callback)

  • This method is designed to be used when React.useTransition is not available.
import { startTransition } from 'react';// Urgent: Show what was typed
setInputValue(input);
// Mark any non-urgent state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});

useTransition

  • React.startTransition does not provide an isPending flag.
function App() {
const [isPending, startTransition] = useTransition();
const [count, setCount] = useState(0);

function handleClick() {
startTransition(() => {
setCount(c => c + 1);
})
}

return (
<div>
{isPending && <Spinner />}
<button onClick={handleClick}>{count}</button>
</div>
);
}

Strict Mode in React 18,

Before this change
* React mounts the component.
* Layout effects are created.
* Effect effects are created.

With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode:

* React mounts the component.
* Layout effects are created.
* Effect effects are created.
* React simulates unmounting the component.
* Layout effects are destroyed.
* Effects are destroyed.
* React simulates mounting the component with the previous state.
* Layout effect setup code runs
* Effect setup code runs

Suspense on the server

React 18 introduces:

  1. Streaming rendering on the server

Deprecations

  • react-dom: ReactDOM.render has been deprecated. Using it will warn and run your app in React 17 mode.
  • react-dom: ReactDOM.hydrate has been deprecated. Using it will warn and run your app in React 17 mode.
  • react-dom: ReactDOM.unmountComponentAtNode has been deprecated.
  • react-dom: ReactDOM.renderSubtreeIntoContainer has been deprecated.
  • react-dom/server: ReactDOMServer.renderToNodeStream has been deprecated.

Concurrency

  • React can interrupt, pause, resume, or abandon a render.
  • This allows React to respond to the user interaction quickly even if it is in the middle of a heavy rendering task.
  • The foundation of concurrent rendering and new features such as suspense, streaming server rendering, and transitions are powered by concurrent rendering.
  • Added support for Suspense on the server and expanded its capabilities using concurrent rendering features.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store