React 18 Alpha: A Quick Overview
Tags: react, javascript, webdev, programming
Published: 2021-06-17 04:05:29

React 18 Alpha has been released last week with cool new features and a working group to understand the community for gradual adoption of new features.

Let's see what are the new features
1. Automatic Batching
2. Start Transition
3. New Suspense SSR
4. Concurrent Suspense

## Automatic Batching
Let first see what is batching? 

**Batching is grouping multiple state update into a single render to optimize the performance.**

Let see this with a code example

{% gist https://gist.github.com/Nilanth/bad45049bf95ded08072db8299990ca3 %}

Try the demo in [codesandbox](https://codesandbox.io/s/react-17-batching-ehwby?file=/src/index.js)

We can see, The **handleClick** has two setState inside it. But when we click the **Next** button the component renders only a single time. You can see the log in console.

Batching already exists in React 17, But React used to batch update only for browser events, not for callbacks. Check the below code for more details

{% gist https://gist.github.com/Nilanth/0db4c4ca659826bda799ded498ac046b %}

Try the demo in [codesandbox](https://codesandbox.io/s/react-17-without-batching-fry7t?file=/src/index.js:0-943)

We can see the component is rendered two times in the console when the Next button is clicked. React does not batch update inside promise, setTimeout or any other events. To overcome this **Automatic Batching** is added in React 18.

**Automatic Batching** performs batch updates in all events. So we get automatically a better performance compared to the older version of React. 

So what we need to do for getting this **better performance** in our app? 

Just update your react version to 18 (as of now 18 Alpha) and add **createRoot** to your **ReactDom** render like below

```
ReactDOM.createRoot(rootElement).render(<App />);
```

Now all your updates are batched automatically. Check the below code example

{% gist https://gist.github.com/Nilanth/1b59c302aa9712ac604b5cb45f7871c3 %}

Try the demo in [codesandbox](https://codesandbox.io/s/react-18-with-createroot-euobe?file=/src/index.js:0-1065)

In the above example, we can see the component is updated only once in the console, Although the states are updated inside the promise. Cool is it, It will improve the app performance by avoiding **unwanted renders**.

If we **don't want to batch** the updates we can use **flushSync** as below

```
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
}
```

## Start Transition
Start Transition classifies the state update into two types

1. Urgent Updates
2. Transition Updates (Slow Updates)

Start Transition mainly focus on the **User Experience** of the app. As updates inside transition run in the background slowly. 

Check the below code

```
import { startTransition } from 'react';
// Urgent: Show what was typed
setInputValue(input);
// Mark any state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});
```

**setSearchQuery** will be interrupted If an urgent update like user interaction events comes in. 

React provide a **hook** for transition with **isPending**

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

**isPending** can be used to show the loading state to the user. If the transition is in progress.

React recommends using **Transition** for remote data and large data updates in UI.

## New Suspense SSR

This feature is for rendering react components in the server. Now suspense supported for server-side rendering also.

First, let us see what is **SSR**?

**SSR** generate HTML from React components on the server and send that HTML to the client. SSR lets the users see the page's content before the JavaScript bundle loads and runs.

**Drawbacks in SSR**
1. Entire HTML need to be rendered in the server and downloaded, To show the UI to the user. 

2. Need to wait till all the JS are downloaded, To make the component **interactive**.

This makes the UX a very bad experience for the users. To overcome this, React has introduced two new features

Two major SSR features are

1. Streaming HTML
2. Selective Hydration

## Streaming HTML

With Streaming HTML react will send Static HTML like Header, Menus to Client as soon as they are ready and will load the heavy lifting components( which depend on data from database like comments component)later once it is ready to stream. So now the user does not require to wait, To see the initial UI render. 

But still, the rendered UI is not interactive it needs to wait till the JS are loaded. So here **Selective Hydration** comes to play

> Hydration is the process of connecting JS to the server-generated HTML.

## Selective Hydration

Selective Hydration prioritizes which component JS needs to be loaded first. When component loading is in progress, If the user tries to interact with any of the components. React will detect that event and hydrate the interacted component first.

These new SSR features will solve

1. No longer to wait to render all HTML in server

2. No longer to wait to load all JS to make the component interactive 

3. No longer waiting for all component to hydrate to interact with the a component.

## Concurrent Suspense

Now Suspense comes with full support. Like 

1. Delayed transitions (waiting for the data to resolve before proceeding with state transitions).

2. Placeholder throttling (reducing UI thrash by throttling the appearance of nested, successive placeholders).

3. SuspenseList (coordinating the appearance of a list or grid of components, like by streaming them in order)

Check the Suspense Example

```
<Suspense fallback={<Loading />}>
  <ComponentThatSuspends />
  <Sibling />
</Suspense>
```

In the above example, React will show the `<Loading />` component at first, and then will replace `<Loading />` component with `<ComponentThatSuspends />` and `<Sibling/>` when the data is resolved in `<ComponentThatSuspends/>`.

New Change in **React 18 Concurrent Suspense** is that nothing inside the `<Suspense />` component will be rendered until the data is resolved! 

But in **Legacy suspense (Suspense in React 17)** sibling component is immediately mounted to the DOM, its effects and lifecycles are fired and it is hidden from UI.

Check the difference between **Legacy suspense** and **Concurrent Suspense** with the examples shared by React Core team.

Legacy Suspense Example -  https://codesandbox.io/s/keen-banach-nzut8?file=/src/App.js

Concurrent Suspense Example -  https://codesandbox.io/s/romantic-architecture-ht3qi?file=/src/App.js


## Let's Try React Alpha Now

To install the latest React 18 alpha, use the @alpha tag

```
npm install react@alpha react-dom@alpha
```

It will take some months to reach Beta from Alpha and will take more time to reach a stable release. Check out the React Working Group for more details.

## Reference
* React Blog - https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html

* React 18 Working Group - https://github.com/reactwg/react-18

Need to learn more? Feel free to connect on [Twitter](https://twitter.com/Nilanth) :)