What’s new in React 18?
Tags: react, react18, javascript, webdev
Published: 2022-04-13 09:00:57


## What’s new in React 18?

The new version of React is out and it is now available on [npm](https://www.npmjs.com/package/react)! It has introduced some new, interesting features. You won’t have to change any code or learn a new concept and very importantly it does not break any of your existing code.

## 👉How To Update

It is fairly simple to update to the latest version of React in your existing project. Follow the below steps to update to React 18,

 1. Update dependencies
```
    // for npm
    npm install react@18 react-dom@18

    //or for yarn
    yarn add react@18 react-dom@18
```

2. Go to your root index.js and make the below changes,
```
    // Before
    import { render } from 'react-dom';
    const container = document.getElementById('app');
    render(<App />, container);
    
    // After
    import { createRoot } from 'react-dom/client';
    const container = document.getElementById('app');
    const root = createRoot(container);
    root.render(<App />);
```

The `React.createRoot` creates a root running in React 18, which adds all of the improvements of React 18 and allows you to use concurrent features. This will be the root API moving forward.

That’s all! You don’t need to make any other code changes 🥳.

## 👉Concurrency

This is the most important concept added in React 18. Concurrency is not a feature, it is an implementation detail. It helps with state update prioritization so that urgent state updates can be prioritized over less urgent/time-consuming/blocking updates.

![React 18 — Concurrency](https://cdn-images-1.medium.com/max/11904/1*jrwGZMyvF1B4ee8yi9Zgjw.png)

A key property of Concurrent React is that rendering is interruptible. React always process all state updates in the order they were triggered i.e. in a single, uninterrupted, synchronous transaction. With the addition of this concurrency concept, you can tell react that a certain state update has a lower priority than the others, and then react will treat other state updates with higher priority.

You can tell react that a state has a lower priority using one of the new APIs that are newly introduced in React 18 — `useTransition` and `startTransition`

## 👉useTransition and startTransition

`useTransition` and `startTransition` let you mark some state updates as not urgent. Other state updates are considered urgent by default.
e.g.
urgent state updates — updating a text input
non-urgent state updates — rendering a list of search results

### useTransition

* Since it is a hook this can be used in functional components.

* It returns an array with two values:
- **isPending**: a stateful value for the pending state of the transition
- **startTransition**: a function to start the transition

### startTransition

* This method is designed to be used when `useTransition` is not available, e.g. class components.

* This lets you mark updates inside the provided callback as transitions.

See the working examples below. We have a list of two thousand users to be rendered on UI. In the first example, we have used the traditional way of rendering the list whereas in the second example we have used the `useTransition` hook. You will notice the performance difference while searching for a user.

In the first example, you will notice a bit of lag while typing in the input box, this is because React is waiting for a filtered list state update and then updates the state of the input box.

And in the second example, we are telling React to keep the list update state on low priority which results in performance improvement.

 1. Without prioritization,
{% embed https://codesandbox.io/embed/demo-no-concurrency-bgnptq?fontsize=14&hidenavigation=1&theme=dark %}

2. With concurrency rendering,
{% embed https://codesandbox.io/embed/demo-usetransition-d04xhk?fontsize=14&hidenavigation=1&theme=dark %}  

**Important Note: **It ****is not recommended to wrap every state update with `startTransition` instead, we should use it only when there is no other solution available to increase the UI performance.

### useDefferedValues()

It tells React to show the old state until a newly updated state is ready. This is similar to `statrTransition()` but can be used where you don’t have complete control over the state updates, e.g. state passed from parent component to a child component. To use this, you simply need to wrap the state variable inside `useDeffedValue()` , and then your child component will get the old state until an updated value is available.

```
    const userList = useDeferredValue(props.list);
```

## 👉New Hooks for Libraries

React 18 has introduced a few hooks,

* useSyncExternalStore

* useInsertionEffect

* useId

>  Note: These hooks are intended to be used by libraries, not application code. As an application developer you will probably ever use these hooks.

## 👉Automatic Batching

Automatic batching allows grouping multiple state updates together so that they get executed as one state update. This results in a single re-render for better performance.

Batching was already present in the older version of React but was limited to React event handlers only. For example, if you have two state updates inside of the same click event, React has always batched these into one re-render. If you run the following code, you’ll see that every time you click, React only performs a single render although you set the state twice:

![Batching in the older version of React](https://cdn-images-1.medium.com/max/2800/1*cFz3ENUAp1GOwlpYLoPrWw.png)

With automatic batching React 18 now support state update batching inside promises, setTimeout, native event handlers, or any other event that was not batched in React by default. See the below example,

![Automatic batching in React 18](https://cdn-images-1.medium.com/max/2800/1*-UJsutIDSiRJRYXO4D8bAw.png)

### What if I don’t want to batch?

Usually batching is safe, but some code may depend on reading something from the DOM immediately after a state change. For those use cases, you can use `ReactDOM.flushSync()` to opt-out of batching:

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

## 👉New Suspense Features

The suspense component is already present in the older version of React. However, the only supported use case was code splitting using React.lazy , and it wasn’t supported at all when rendering on the server. You must have been using the Suspense component to show a fallback component until another component is ready for rendering i.e. lazy loading of components.

```
    <Suspense fallback={<Spinner />}>
      <LaziComponent />
    </Suspense>
```

React 18 allows Suspense work for server-side rendering and in case of data fetching in near future.

## 👉Server Components

React introduced Server Components however these are still in the research and development phase. These components are meant to render on the server only allowing to perform certain server-side only logic. This will be used to perform tasks on the server that should not run on the client may be for security or performance reasons.

This is an experimental feature and not ready for you to use in your app. We are expecting this to be released in near future. More details are available [here](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html).

### And more...
- Check [Hybrowlabs](https://hybrowlabs.com/react-js-dev-outsourcing) for React app development services.