Review of React 18 updates: briefly and succinctly

Review of React 18 updates: briefly and succinctly

In this article, we will look at some of the updates that React 18 has prepared for us — we will analyze automatic batching, concurrent rendering, changes in the architecture of pausing rendering on the server side and new hooks.

I will add code examples to the updates, and what needs to be done to start using the new functionality.

Automatic batching

React 18 adds the ability to automatically batching state updates for asynchronous operations. For example, promise, timeouts, fetch requests. This has a positive effect on productivity.

Batching in React refers to the process of grouping multiple state update calls into one re-render stage. In other words, batch processing.

Previously, grouping took place only inside event handlers.

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

  function handleClick() { 
    // До React 18 следующие вызовы не батчились
    // Установка состояния происходит «после» события в колбэке асинхронного вызова
    fetchSomething().then(() => {
      setCount(c => c + 1); // Спровоцирует ререндер
      setFlag(f => !f); // Спровоцирует ререндер
    // В React 18
    fetchSomething().then(() => {
      setCount(c => c + 1); // Не вызывает ререндер
      setFlag(f => !f); // Не вызывает ререндер
// React будет вызывать ререндер только один раз, в конце
  return (
    <button onClick={handleClick}>Next</button>
    <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>

Concurrent rendering and new hooks

Concurrent rendering (competitive mode) is designed for smoother operation of the application on the user’s device. One of the areas of application is interrupted rendering. Imagine that a user enters text into the search bar. The event updates the state of the component, and a new list of results is rendered. During this process, the input sticks: the browser cannot update the text entered in the field, because it is engaged in rendering a new list of results. Competitive mode corrects this limitation and makes rendering interruptible.

With the new features of competitive rendering, new APIs were added: state transitions, delay features (Suspense) and new hooks.


The API method is added to update the state of the component, which entails heavy calculations. For example, filtering a list. This allows you to significantly improve user input and interface response, because it marks heavy component updates as “transitions” – transitions.

The API is represented as a function startTransition, in which updates of states that are non—urgent are placed – non-urgent.

import { startTransition } from 'react';

// Срочное (urgent) обновление: отображаем введенный текст

// Помечаем обновления состояний как переходы
startTransition(() => {
  // Переход: фильтрация списка по введенному ключевому слову

startTransition useful if you want to make user input fast, there was no UI frieze, and non-urgent operations were performed in the background.


Besides startTransition there is a new hook useTransition. It allows you to find out the status of the transition:

import { useTransition } from 'react';
const [isPending, startTransition] = useTransition();


Returns a deferred version of the passed value, which will “lag” behind the original one for a time equal to the timeout:

import { useDeferredValue } from 'react';
// ...
const [text, setText] = useState("text");
const deferredText = useDeferredValue(text, { timeoutMs: 2000 });

When a new hook is useful: you need to implement a responsive and fast user interface. The component that the user interacts with will be quickly redrawn for each input. At the same time, unnecessary re-renderings of the heavy component will not occur.

Suspense Improvements

Suspense is designed to display a spare interface (spinner) while waiting for child components. Child components can make asynchronous API calls at this time, or load via lazy load.

The main innovation is that the feature has become stable. It received major architectural changes under the hood and acquired the name “Competitive Delays” (Concurrent Suspense). Changing the name will not affect React users in any way. A significant change for users is the rendering of child elements inside Suspense:

const App = () => {
  return (
<Suspense fallback={<Loading />}>
<SuspendedComponent />
<Sibling />

In React 17 , the component <Sibling /> it will be mounted and its effects will be triggered. Then it will be hidden.

Now there is a component in React 18 <Sibling /> it is mounted only after <SuspendedComponent /> it will load.


Designed to determine the order in which nested components are loaded and displayed directly to the user Suspense and SuspenseList.

<SuspenseList revealOrder="forwards">
<Suspense fallback={'Загрузка...'}>
<ProfilePicture id={1} />
<Suspense fallback={'Загрузка...'}>
<ProfilePicture id={2} />
<Suspense fallback={'Загрузка...'}>
<ProfilePicture id={3} />

There are cases when it is necessary to display components in a certain order on the UI. If you wrap them in ​​SuspenseList, then React will not display the component until the previous one from the list is loaded.

Streaming SSR

Major improvements have been made to Suspense Server-Side-Rendering (SSR). Consider the main features:

Selective hydration.

Method hydrate() it is used in SSR and allows you to hang event handlers on DOM tree nodes that have been rendered on the server side. This allows you to improve the customer experience when the page is first loaded.

React will start hydrating the components, taking into account the user’s interaction with the content of the site. For example, when clicking on a comment, React prioritizes the hydration of HTML parent blocks.

Another feature is that React will not block the UI during hydration — this process will occur during browser downtime. Therefore, user events will be processed immediately.

Streaming HTML

Allows you to send HTML to the client without downloading all the data for rendering to the server. As soon as the data is received, it will be rendered on the server and sent to the client. For example, there is a block with comments, and we can asynchronously load information on them, giving HTML. When the comments are received, render them and send them to the client at the end of the HTML document.

What do I need to do to use the new React 18 functionality?

Update. Installing the latest version

npm install react react-dom


yarn add react react-dom

Updating the Rendering API

React 18 introduces a new root API that provides better ergonomics for root management. The new API also includes new parallel rendering, which allows you to use parallel functions.

// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(, container);
// After
import { createRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = createRoot(container); 

If your application uses server-side rendering with hydration, update hydrate before hydrateRoot:

// Before
import { hydrate } from 'react-dom';
const container = document.getElementById('app');
hydrate(, container);

// After
import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = hydrateRoot(container, );

Outsourced Development Services | Unreal Engine Development

Ready to see us in action:

More To Explore
Enable registration in settings - general
Have any project in mind?

Contact us: