What’s new in React 18?

React 18 was released in March 2022. This release focuses on performance improvements and updating the rendering engine. React 18 sets the foundation for concurrent rendering APIs that future React features will be built on top of.

Features

  1. Concurrent React
  2. Automatic Batching, Transitions, Suspense on the server
  3. createRoot, hydrateRoot, renderToPipeableStream, renderToReadableStream
  4. useId, useTransition, useDeferredValue, useSyncExternalStore, useInsertionEffect
  5. Strict mode
  6. ReactDOM.render, renderToString – Deprecated/discouraged

Now let’s look at each of these updates in more detail.

 If you don’t know how to update React Click Here.

Concurrency in React 18

To understand concurrency, let’s consider this example by Dan Abramov from React 18 Working group discussions.

Let’s say that we need to call two people – Alice and Bob. In a non-concurrent setting, we can only have one call at a time. We would first call Alice, end the call, and then call Bob.

This is fine when calls are short, but if call with Alice has a long waiting period (such as on-hold), this can be a time sink.

Image showing that in a typical non-concurrent phone conversation, you have to wait for a call to be over before starting a new call.

In a concurrent setting, we could call Alice and, once we were put on hold, we could then call Bob.

This doesn’t mean that we are talking to two people at the same time. It just means that we can have two or more concurrent calls at the same time and decide which call is more important.

Image showing phone conversation between Alice and Bob can be concurrent, by placing a call on hold and answering a more urgent call with Bob first.

Similarly, in React 18 with concurrent rendering, 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.

Before React 18, rendering was a single, uninterrupted, synchronous transaction and once rendering started, it couldn’t be interrupted.

Concurrency is a foundational update to React’s rendering mechanism. Concurrency allows React to interrupt rendering.

React 18 introduces the foundation of concurrent rendering and new features such as suspense, streaming server rendering, and transitions are powered by concurrent rendering.

Automatic Batching

React 18 features automatic batching. To understand batching, let’s consider the example of grocery shopping from the same React Working Group discussion.

Let’s say that you are making pasta for dinner. If you were to optimize your grocery trip, you would create a list of all the ingredients that you need to buy, make a trip to the grocery store, and get all your ingredients in one trip.

This is batching. Without batching, you would start cooking, find out you need an ingredient, go to the grocery store and buy the ingredient, come back and continue cooking, only to find out you need another ingredient, go to the grocery store…and drive yourself crazy.

In React, batching helps to reduce the number of re-renders that happen when a state changes, when you call setState. Previously, React batched state updates in event handlers, for example:

const handleClick = () => {
setCounter();
setActive();
setValue();
}

//re-rendered once at the end.

However, state updates that happened outside of event handlers were not batched. For example, if you had a promise or were making a network call, the state updates would not be batched. Like this:

fetch('/network').then( () => {
setCounter(); //re-rendered 1 times
setActive();  //re-rendered 2 times
setValue();   //re-rendered 3 times
});

//Total 3 re-renders

As you can tell, this is not performant. React 18 introduces automatic batching which allows all state updates – even within promises, setTimeouts, and event callbacks – to be batched. This significantly reduces the work that React has to do in the background. React will wait for a micro-task to finish before re-rendering.

Automatic batching is available out of the box in React, but if you want to opt-out you can use flushSync.

Transitions

One of the most significant updates of React 18 is the introduction of startTransition API that keeps your app responsive even during the large screen updates.
Sometimes during heavy update operations, your app became unresponsive, the startTransition API can be very useful to handle such situations.
The API allows users to control the concurrency aspect to improve user interaction. It is done by wrapping heavy updates as “startTransition” and will be interrupted only if more urgent updates are initiated. Thus it actually classifies urgent updates and slow updates.
If the transition is interrupted by the user actions, React will throw out the stale rendering work that hasn’t yet finished and will render only the latest update.

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:

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);
});

How are transitions different from debouncing or setTimeout?

  1. startTransition executes immediately, unlike setTimeout.
  2. setTimeout has a guaranteed delay, whereas startTransition’s delay depends on the speed of the device, and other urgent renders.
  3. startTransition updates can be interrupted unlike setTimeout and won’t freeze the page.
  4. React can track the pending state for you when marked with startTransition.

New Suspense SSR, architectural improvements

React 18 has added an architectural improvement to the react server-side rendering. Server-side rendering generates HTML from the react components on the server and sends it back to the client, so the client can now see the page content before the JavaScript bundle load and run.
Well, there is a drawback of SSR.

  1. It does not allow components to wait for data. That means before rendering HTML to the client, you must have your data ready for components on the server.
  2. You need to load the JavaScript for all components on the client before hydrating any of them to make them interactive.
  3. Also, you need to wait for all the components to be hydrated before interacting with them.
  4. The problem can be overcome using two new features of suspense, i.e Streaming HTML and Selective hydration.

Streaming HTML on the server

With the streaming HTML, React will send the static pieces of UI components using suspense, which will decide which part of the component will take longer to load and what can be directly rendered, so the user does not need to wait to see the initial UI render.

Selective Hydration on the client

With selective hydration, components that are wrapped under suspense will not block hydration. Once the JS and content are loaded for each component it will start hydrating without blocking another component.

For more information refer to React 18 GitHub discussion.

Strict mode

Strict mode in React 18 will simulate mounting, unmounting, and re-mounting the component with a previous state. This sets the ground for reusable state in the future where React can immediately mount a previous screen by remounting trees using the same component state before unmounting.

Strict mode will ensure components are resilient to effects being mounted and unmounted multiple times.

Conclusion

In a summary, React 18 sets the foundation for future releases and focusses on improving the user experience.

Upgrading to React 18 should be straightforward and your existing code should not break after the update. The upgrade process should not take more than an afternoon.

Related Posts

semantic html

SEO Secret Weapon: Leverage Semantic HTML for Better Results

In the ever-evolving world of SEO, the key to success lies in clear communication, not just with your users, but also with search engines. This is where…

React Data Fetching & Management

Level Up Your React: Data Fetching & Management

Welcome back to the React 101 series! In this edition, we’ll learn about how to fetch data from APIs and manage data flow within your React applications….

secure nodejs

Securing Your Node.js Application: Best Practices and Strategies

Node.js is a popular and powerful runtime for building server-side applications with JavaScript. However, as with any web application, security should be a top priority. In this…

learning css variables

Learn CSS Variables and Theme Your Websites Like a Master

Elevate your web development game by embracing the power of CSS theming and providing users with a visually captivating and personalized experience.

React 19 New Features

React 19: New Features and Upcoming Major Releases in 2024

Get ready for some exciting news from the ReactJS official blog! If you love ReactJS, you’re in for a treat. We’ll take you through the latest cool stuff, like the supercharged React Compiler, the game-changing Actions, and new features in React Canary.

building ui elements with jsx

Building UI Elements with JSX and Components

Ready to dive into React? This chapter unlocks the secrets of JSX – writing HTML right in your JavaScript! We’ll also explore components, the reusable powerhouses of React .

Leave a Reply

Your email address will not be published. Required fields are marked *