Late to React 18? My Top 4 awesome features and real-use examples.
Opeyemi Stephen
Posted on July 8, 2022
Reading this, you probably know what React is and might have upgraded to React 18. This article is aimed at informing code newbies in detail and increasing beginner understanding of the awesome feature updates of React v18.0 which I discovered while using it myself.
First up, what is React?
React is an open-source, JavaScript front-end library for building user interfaces. It works fast, is easy to learn, and is efficient, especially in creating scalable and reusable UI components.
Back in March, the React team announced the release plan for the upcoming stable version of React. With that being said, let’s explore...
You might have to upgrade to React 18 if you haven't already done that.
How to upgrade to React 18.
Install React and react-dom. You can use npm and then create a react application here.
Change ReactDOM.render to ReactDOM.createRoot. Do this by finding the index.js file in the root and changing accordingly:
Create root with
const root = ReactDOM.createRoot(container);
Render app to root with
root.render(<App />);
Root is how React updates the DOM tree. It makes all of the new features such as concurrent rendering and automatic batching available to the developer.
New features and concurrent rendering will be turned off if the root isn’t added. The app will behave like it’s on React 17.
So what changed?
With React 18, the concept of Concurrency/ concurrent React is no longer all-in or nothing as you can pick wherever you want to have the concurrency feature enabled. It doesn’t have to be bound to the entire app
The new features of v18 include:
- Automatic Batching
- Transitions
- Suspense on the server.
Automatic Batching:
This is simply making a list of items so you can perform a list of micro-tasks at once. React does not have to spend time re-rendering the same work over and over again when it can do it at the end of the micro task.
Take a look at the code block of the event handler with 3 set states below;
function handleClick() {
setIsFetching(false);
setError(null);
setFormStatus(‘success’);
};
React could batch all three, look at them one by one and re-render them in the previous version. What React couldn’t do was batch and re-render anything that wasn’t an event handler like an async callback or a promise.
React 18 fixes that as all updates, even within promises, the function will be batched which will improve the performance of the app.
Concurrency:
It is a feature by which React can pause and resume rendering events to improve performance.
For instance, say you have a work call with a teammate in your team and your wife calls you while on the call for an urgent conversation. You can leave the call with your teammate, go on to speak to your wife, and then come back to the call. That is Concurrent rendering.
It is the ability for React18 to interrupt, pause or abandon a render in order to improve performance or perform urgent updates.
- Rendering was a single synchronous task that could not be interrupted once started before React 18.
- Concurrent rendering can be said to be a technical foundation that most features of React18 are built upon.
- It happens behind the scenes and the dev doesn’t need to bother about it.
- It enables React to prepare multiple new screens.
- It also enables reusable state, such that sections of UI from the screen can be removed and added back later while reusing the previous state, for example, tabbing away and coming back to the screen.
- Concurrent mode before React 18 usually meant that concurrency was used in all of the app but now it is used in only the parts the dev wants. Cool right?
Transitions:
This simply means how you as a dev instructs React to prioritize certain updates and mark non-urgent updates as transitions.
Take a random google search for instance, two feedbacks from character and population of the query are two different experiences a user would have.
Transitions will help to prioritize the display of characters typed in by the user as urgent and then the query as a non-urgent priority.
This can be quite helpful for people with slow computers or slow internet connections.
Anything that is an urgent state is put in a normal state and anything that is not urgent is put in a startTransition
.
import { startTransition } from ‘react’;
// Urgent: show what was typed
setInputValue(input);
// Mark any state updates as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});
This means that if a user for instance is searching for the term “Soccer”, the transition will prioritize displaying the letter “s” and other letters after every keystroke before querying the search parameters.
And if you want to do something while transition is happening, you can use a hook called useTransition
that gives access to two parameters, isPending
and startTransition
. Real-life use cases?
-
isPending
can be used for loader states -
startTransition
can be used when there is a slow rendering from maybe a heavy data app like Slack or Jira,startTransition
can help.startTransition
can also be used in cases where the network is slow but with libraries like Relay which has it in-built because it needs Suspense.
Suspense on the Server
In React 18, it is now powered by code-splitting too. What this means is that, take, for instance, you have an app and certain parts of your app are really slow, in the other versions of React, you had to wait for the app to finish loading completely before the HTML could be shipped. (before the entire rendering process could be done and shipped to the client-side).
Recall that server rendering is simply when HTML is created on the server and sent over to the client. It helps end-users in the sense that they can see at least a UI much faster than any other thing like JS has been loaded as opposed to rendering on the client-side.
However, despite that seeming improvement brought, certain components could not be isolated/split, and the rest "server-rendered" separately. It was all or nothing.
With React 18, if one part of your app is slowing down the rest of the app, you can put that component in suspense and tell React to load that particular component separately and send the rest of the page to the user while that isolated part can get a loader or spinner state.
When that part is ready, React 18 will send the HTML in the same stream and it all happens before any JS is loaded so it is pretty fast for the user and decreases the time it takes for the user to see the first page. Do not forget images to represent server rendering.
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
In summary, suspense on a server will make sure:
- one slow part of an app or page doesn’t slow down the whole page
- to show initial HTML early and stream the rest
- code splitting fully integrated with server rendering is achieved
Other awesome changes of React 18 include:
- Client-side features include changes from
render
tocreateRoot
,unmountComponentAtNode
toroot.unmount
andReactDOM.Hydrate
tohydrateRoot
. - React 18 also has hooks like
useId
,useDeferredValue
,useSyncExternalStore
,useInsertionEffect
which are new Library APIs. - Server API changes include
renderToPipeableStream(Node)
andrenderToReadableStream.(edge env)
. - Updates have also been made to strict mode
-
ReactDOM.render
andrenderToString
have been deprecated.
How does it affect the codebase when updated? The React team has stated that;
- The code should work just fine.
- Some components might behave slightly differently with concurrent rendering.
- Some components may require migration efforts.
- New rendering behavior is only enabled in parts of your app that use new features.
What Strategy to update when upgrading to React 18?
- Upgrade to React 18 without breaking code.
- Gradually start adding concurrent features. Use a library that powers concurrent features
- Use StrictMode to surface concurrency-related bugs in the dev environment.
- Start using concurrent features after upgrading to React 18. Overall, most apps should work fine after the upgrade without too many issues.
Edge cases to watch out for
- StrictMode is stricter but can be disabled
- flushSync() will disable automatic batching
- Concurrent features might require library updates.
That's all for now. I hope this helps a newbie get comfortable with React 18.
So I decided to do this thing where I refer you to a song at the end of every article because what's coding without a little music. Others give lofi, I recommend Afrobeats. For this article's edition, I recommend listening to the new Burna Boy album titled Love, Damini.
PS: These things are not sponsored, I just want to share good music while giving you great articles.
Posted on July 8, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.