ReactJS

Introduction

React 18 is the newswest buzzword in the community of JavaScript developers. Used for building UI components, React 18 was released in March 2022. This latest version React 18 primarily focuses on improving the performance and updating the rendering engine. In June 2021, the React team announced the upcoming launch of React 18 and what was to come. In December 2021, the prime focus of React Conf 2021 was the newly launched concurrent rendering features of React.

React Conf 2021 Recap

It introduces many under-the-hood new features and some out-of-the-box performance improvements. So let’s explore all of it.

 In React 18, we have two root APIs.

1) Legacy root AP: This API is called with ReactDOM.render.

reactcode

2) New root API:- This API is called with ReactDOM.createRoot. After running this API we can add all the new features of React 18 to our project. We have to import it from React-dom/client.

What is new in React 18?

Concept:-

  • Concurrency

Features:-

  • Automatic Batching
  • Transition
  • Suspense on the server

APIs:-

  • createRoot
  • hydrateRoot
  • renderToPipeableStream

Hooks:-

  • useId
  • useTransition
  • useDeferredValue
  • useSyncExternalStore

Deprecated:-

  • ReactDOM.render
  • renderToString
  • Updates in Strict mode.

How to use React 18?

We have to hit the following command

  • npm install React React-dom / yarn add React React-dom

In your index.js file replace ReactDOM.render to ReactDOM.createRoot.

3

Concurrency

Concurrency means tasks that can overlap. Let’s understand it with a phone analogy.

No concurrency means that I can have a conversation with one person at a time. If I’m talking with John and get a call from Jane then I have to first end the conversation with John and then will be able to start the conversation with Jane.

Concurrency means I can have more than one conversation at the same time. For example, if I’m talking with John and get a call from Jane then I will put John on hold and start talking with Jane.

It doesn’t mean that I can talk with two people at the same time. It means I may be in multiple conversations but I will choose who to talk to first based on priority.

Concurrent vs Non-concurrent

The difference between concurrent and non-concurrent, In non-concurrent, if we have two processes A and B and we are interacting with A, But if we want to interact with B then we have to kill/end process A first then only we are able to interact with B. Whereas in concurrent we don’t need to kill/end any process to interact with other processes. It’s up to us which process is more important for us.

useTransition Hook

In React 18, React came up with a concept called Concurrency.

By default, all state updates in React are considered urgent, which is not used every time because sometimes we want an immediate state update as soon as we interact with it, like selecting a value from the dropdown, or typing into the input box. But with the useTransition hook, we can mark UI updates as low priority. Which is very useful for heavy non-urgent updates.

We mark updates as non-urgent or low priority is called transition.

Let’s understand it with an example. For example, we have one input box and 10,000 products listed. So when we type something into the input box and then the filter logic works, but if the user hasn’t had a high processor system then it might take time to update the state and reflect it to the UI. So what will happen, until the product filtering process is not done and the state is updated we also have to wait for the input value change which is not a good user experience. So with this scenario input state change is a higher priority and the filtering process has a lower priority.

We can achieve this with the help of the useTransition hook.

Let’s look at the syntax of the useTransition hook.
4

useTransition hook returns an array of 2 items.

  1. isPending:- It shows whether that transition is in a pending state or not.
  2. startTransition:- It is a function, in which we can mark UI updates as transitions.

5

When we wrap our group of states into the startTransition method then that group of state updates has low priority as compared to other state updates. 

As we can see in the above example, our filterTerm state has low priority and we can show a loading indicator until that low-priority state gets updated. This is very useful to improve the user experience of our web application. Otherwise what will happen if both states are urgent then if the user types something into the input box then until the filter state has not been updated, the user also has to wait to get the value in the input box, which he has entered. 

useDeferredValue

useDeferred value works the same as the useTransition hook. So when to use one over the other.

We have to use the useDeferred value when we don’t have control over our state or state updation logic you could say.

Remember the example which we discussed in the useTransition hook. In that example, if the state updation and filtering logic is done from the server side and we don’t have control over it, then how can we mark our state as low priority or transition you could say?

So in this type of scenario, we have to use the useDeferredValue hook. useDeferredValue takes the value and returns the deferred value.

First, we have to import it from React. In this example let’s assume that the products which we are receiving via props, are what we are getting from API.

6

Automatic Batching

Batching means when a group of states gets updated together within browser events or event handlers ( onChange, onClick, etc..). So in batching our group of state updates first and then our component will re-render one time, Which gives us a performance boost. No matter how many groups of states we are updating it will re-render only one time for every batching.

But before React 18, if we tried to update our group of states outside of browser events or event handlers, batching was not happening and components were rendering for every state update. E.g. We have a group of 3 states and we update them then our component will re-render 3 times.

7

So if you try to run both examples in React 17 then you will see that in the first example, our component will re-render only once.

When a group of states updates within event handlers and hooks is called batching. So for every state update, it prevents re-rendering and gives us a performance boost.

Before React 18, batching only worked in browser events. Like onClick, onChange.
But React 18 introduced a new feature called Automatic Batching. It will enable batching for all state updates, no matter where we are updating them.

If you run this code and see an output then you can see that when you click on the button, batching will be done for both state updates and the console.log message will display only one time.

It works fine and there is no issue. But what if we try to update both states outside of the browser events?

Let’s take a look.

In this example we try to update both states in the callback of a fetch() and fetch is not a browser event, so batching will not happen. And when we click on submitAsyncHandler, we will see a console.log message for each state update. So here we will see two console.log messages on every click.  This will happen only if you are using React version below 18.

This will not happen if you are using React version 18, so with version 18, the concept of Automatic Batching will be applied and when we run this code, we will see only one console.log message for every click, no matter how many states we are updating together.

Why did React introduce Automatic Batching?

If we have a small web application then these unnecessary re-renders will not affect, but when our web application grows and becomes a large web application then these unnecessary re-renders will slow down the performance of our application.

How to stop Automatic Batching?

Sometimes, you go through a scenario where you don’t want batching and want to have a re-render for every state application. So for that, React provides a flushSync method, which can be imported from React-dom.

Once we import flushSync from React-dom, we have to put our group of state updates into the callback of the flushSync method. As we have seen previously when a group of state updates happen then automatic batching is applied (if you are using React 18) and we get only one re-render for every batching. But after using the flushSync method we will re-render for every state update.

8

useId Hook

useId hook is used to generate a unique random ID. We can generate unique random IDs on both the client side and the server side.
Before the useId hook, we had useOpaqueIdentifier, but it had many bugs. So the React team solved all of those bugs and introduced useOpaqueIdentifier with the new name called useId.

When we generate a new unique Id with useId hook, it always gives us a string. With the help of the useId hook, we can join two React elements.

9

image1

So as you can see, we generated a unique id from useId and displayed it and we gave that id to both labels so we concat that id with our id’s name. But one thing to remember is that we can’t give CSS to that id which we generate from useId.

We can concat or prefix another string with our unique generated id. We just have to add a second argument as an object {identifierPrefix: ‘YOUR_PREFIX_STRING’ } of root in index.js / tsx file.

10

image2

As you can see after adding our string as identifierPrefix we get a prefix to our every ID.

Another thing to remember is that we should not use these Ids in Listing. This point is mentioned in the official documentation of React.

renderToPipeableStream

It is a node.js specific API. To use this API first we need to import ReactDOM from ‘React-dom/server’ then only we are able to use renderToPipeableStream.

11

It is used to render a React element to its initial HTML. It will return pipe and abort methods. It supports suspense and streaming.

Let’s understand the above example and what these methods are actually doing.
First, we have the onShellReady method. In this method, we can set the error code if we get some error before we start the streaming.
E.g.

12

The Second method is the onShellError method. It is used to emit an alternative shell. In this, we write the code for if some error occurred before we complete the shell so we emit an alternative shell.

13

Next one is the onAllReady method. This method will run when the content of the entire page is ready. When we don’t want to stream, we should go for this method instead of onShellReady. For a static generation, we can use this method.

14

useSyncExternalStore

Before diving into useSyncExternalStore, first let’s understand related concepts to useSyncExternalStore.

It’s a lower-level API.

External Store: Redux store, Mobx store, global variables, DOM states, etc.

Internal Store: Props, useState, useReducer, context e.t.c.

Tearing: Tearing means we get different values for the same state.

Tearing is happening in React 18 because of the way concurrent features of React 18 work. We can pause re-rendering and between that pause how external stores communicate with React to trigger re-render and that’s why we get the different values of the same state.

So we have a new API that lets you do the same.

15

Suspense

Suspense is a React component that suspends a component from being re-render. Until the component is in suspense, it will display fallback options. We must pass a value into fallback. It could be a string or some component like Spiner.

Suspense only works with dynamic import or lazy loading.

Looking to Upgrade to React 18?

We can certainly help you with any queries related to React.js development, migration to React 18, or upgrade services. Update your existing web application to the latest React.js version and avail the potential benefits. Hire React Developers from Bytes Technolab to get greater ROI as these experts will also make recommendations to give your web app and business a competitive edge.

Bytes Technolab Inc. is a leading React.js Web Development Company that has been delivering expert web app solutions to global startups, SMEs, and enterprises. Hire a remote team or hire full-time web developers individually having an average experience of 4+ years. It is a brilliant opportunity to accelerate your web app development project while adding value to your overall business ecosystem.

Contact us now to hire React developers to get your hands on React 18!

Related Blogs

AI-Powered Medical Imaging: Bringing Precision Healthcare into the Future

AI-Powered Medical Imaging: Bringing Precision Healthcare into the Future

Many new healthcare advances will arise when artificial intelligence and medical imaging combine. The aspect that changes is as immense as the s...

Selecting the Best Adobe Experience Manager Solution for Your Needs

Selecting the Best Adobe Experience Manager Solution for Your Needs

Creating and managing engaging content across various platforms is important for eCommerce stores in this ever-evolving digital commerce era. Th...

How Adobe Commerce Development Partner Boosts Your eCommerce Success?

How Adobe Commerce Development Partner Boosts Your eCommerce Success?

Modern retail owners have turned to accredited eCommerce development companies as their technical consulting and implementation partners. By han...