DEV Community

Cover image for React 18 - New Features & Improvement Strategies
Bidisha Das
Bidisha Das

Posted on • Updated on

React 18 - New Features & Improvement Strategies

On March 8th, the React team released the React 18 RC(Release Candidate). The latest release has brought a number of new features that would transform the coding pattern in a number of application. It brings along with it, a couple of performance improvements which I will be covering in this blog.

Concurrency

Concurrency is a property of systems where several processes are executing at the same time, and may or may not interact with each other. Too complex? Let's break it down. Let's say there is a race that is being conducted. Now, concurrency is how many people are running for a single race in a parallel track.

Concurrency

Concurrency is a new feature that React 18 has introduced. It is a new behind-the-scene mechanism that enables React to prepare multiple versions of the UI at the same time.

In this mechanism, unlike previous cases, React may start the rendering, pause in middle for some critical task and resume rendering again. The only thing to keep in mind is that it may also abandon in process render altogether. React guarantees that the UI appears consistent even though the render is interrupted.

This gives the capability of React to prepare screens in the background - without blocking the new thread!

Suspense for Server Side Rendering

Suspense in Server Side Rendering

React has brought forth the feature of Suspense in Server side rendering frameworks like Next.js, Relay, Hydrogen or Remix. React 18 introduces:
Code splitting on the server with suspense, and
Streaming rendering on the server.

Automatic Batching

Batching is the phenomenon via which React groups multiple state updates into a single re-render for better performance optimisation.

Batching

Previous to React 18, batch updates were performed for react-based event handlers. However for promises, setTimeouts, native event handlers or any other events, batch updates were not performed. React 18 performs automatic batch updates for the above mentioned cases too.

Let's understand this using a code.

setTimeout(() => {
  setCount(count => count + 1);
  setFlag(flag => !flag);
  // React will only re-render once at the end (that's batching!)
}, 1000);

Identically, the above code behaves the same as this:

fetch(/*...*/).then(() => {
  setCount(counter => counter + 1);
  setFlag(flag => !flag);
  // React will only re-render once at the end (that's batching!)
})

In case, you don't want to batch, you can use ReactDOM.flushSync() . Let's understand with a bit of code

import { flushSync } from 'react-dom'; // Note: react-dom, not react

function handleFlushesClick() {
  flushSync(() => {
    setCounter(counter => counter + 1);
  });
  // React has updated the DOM by now
  flushSync(() => {
    setFlag(flag => !flag);
  });
  // React has updated the DOM by now
}

Transitions

This feature distinguishes urgent vs non-urgent updates. An urgent update is one which needs immediate response. Urgent updates include actions like clicking, pressing, typing - things that require immediate response or where the user expects the UI to respond immediately.
No intermediate values are to be displayed on screen.

Transition example

A real life example

Considering a real life example, let's think of a debounced typeahead. Now, while you type in the input, you expect the input box to reflect the values typed. However, do you expect the result to appear immediately? No right! It will debounce and then you get result. So , there is some transition time from the time you type your input till the time you get your suggestion. This time frame will be used for transition.

Typically, for best user experience, a single user input should result in both urgent and non-urgent update.

import {startTransition} from 'react';

// Urgent: Show what was typed
    setInputValue(input);`

// Mark any state updates inside as transitions
  startTransition(() => {
     // Transition: Show the autosuggestion based on the input 
        value
      setSearchQuery(input);
});

Search bar

Another real-time example

const [isPending, startTransition] = useTransition()

Here the useTransition hook has 2 parameters that is destructured.

isPending : to denote if the UI update is still in transition state

startTransition: A function that executes code for transactions.

function handleClick() {
   startTransition(() => {
     setTab('comments');
   });
}

This function gets called when you want to switch from Photos tab to Comments tab.


<Suspense fallback={<Spinner />}>
<div style={{ opacity: isPending ? 0.8 : 1 }}>
{tab === 'photos' ? <Photos /> : <Comments />}
</div>
</Suspense>

During the transition phase, while the new UI is being prepared by React, the tab with the Photos UI will be now shown to the user with 80% opacity to give a smooth view of transition.

Strict Mode in React

The Strict Mode in development server brings forth a couple of interesting changes in React 18. This mode essentially provides out-of-box performance for React.

This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

The series of events during mounting now:

I. React mounts the component.

  • Layout effects are created.
  • Effects are created.

II. React simulates unmounting the component.

  • Layout effects are destroyed.
  • Effects are destroyed.

III. React simulates mounting the component with the previous state.

  • Layout effects are created.
  • Effects are created.`

During unmounting, the following events occur

I. Layout effects are destroyed and Effect effects are destroyed.

New Hooks

Image description

a. useId

useId is a new hook for generating** unique IDs on both the client and server*, while avoiding hydration mismatches. This generates an **unique string containing : which does not collide with css selectors and querySelectorAll*

You can also use userId with identifierPrefix in order to prevent collision in multi-root applications. For multiple IDs in the same component, append a suffix using the same id.

b. useDeferredValue

useDeferredValue will let you defer re-rendering a non-urgent part of the tree. Remember we talked about non-urgent rendering? It is no fixed time delay, so React will attempt the deferred render right after the first render is reflected on the screen.

c. useSyncExternalStore

useSyncExternalStore is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. It removes the need for useEffect when implementing subscriptions to external data sources.

Code snippet:

   const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot]);

subscribe: function to register a callback that is called whenever the store changes.
getSnapshot: function that returns the current value of the store.
getServerSnapshot: function that returns the snapshot used during server rendering.

d. useInsertionEffect

useInsertionEffect(didUpdate);

useInsertionEffect is a new hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. This hook will run after the DOM is mutated, but before layout effects read the new layout.

This hook will help in calculating layout in sync with the concurrent re-rendering.


Conclusion

There are others small but significant updates too - for example using the createRoot() hook rather than ReactDOM.render. This method will be used to render a DOM element and umount using root.unmount()

Other than than React also have streaming Suspense support for servers using renderToPipeableStream& renderToReadableStream

React developers keeps on focusing on the enhancement and improvement and couple of bug fixes in this released version. The update is not meticulous and can be done in a morning session, itself. So what's the wait for , application developers? Let's upgrade our library and start working! Kudos to the React team!

Discussion (36)

Collapse
tsgoswami profile image
Trishnangshu Goswami

Going through React docs and understanding new features gives little discomfort, instead this blog explains things each and every details with a very suitable example which anyone can easily understand with quick read. Amazing. Great job 👍🏻👍🏻.
Keep posting such blogs… Will collaborate someday.

Collapse
officialbidisha profile image
Bidisha Das Author

Thank you so much. You're the inspiration! :)

Collapse
rickdelpo1 profile image
Rick Delpo • Edited on

Hi there React Devs, I am a beginner and struggled with React last year for about one month and then I switched to Plain JS because React seemed over my head. I wrote a dev article here at dev.to/rickdelpo1/react-vs-plain-j... outlining 17 reasons why I switched back to Plain JS. Am I being too shorted sighted? Am I missing something about the value of React?

Collapse
officialbidisha profile image
Bidisha Das Author

See , what I feel is maybe you need to go through better courses or maybe educative.io Or frontendmasters. They are really good to follow and will guide you through.

You can only be great in React is you are really really good in JavaScript.

Collapse
rickdelpo1 profile image
Rick Delpo

ok thanks, now I see the problem is that I am not that great with JS because I am mostly a backend developer. So perhaps Plain JS is more my speed. But I still have a hankering for React so will search for easier tutorials on the topic.

Thread Thread
johnyepthomi profile image
JohnYepthomi • Edited on

I feel the more familiar you get with JavaScript , it will make learning React easier for you. I taught myself web development on my own for the most part and I can say that I found react to be easy to understand as I had a better understanding of JS and also that I read through React Documentation and learn about details of component lifecycles etc and the rest follows.

The faster you familiarise yourself with reading Documentations , you will save yourself a lot of time and will improve your understanding of the library etc. I've adopted this habit and It's very very helpful.

Keep your JS fundamental strong and keep building on them gradually, Read MDN Documentation beyond just looking something up.

Embrace the ASYNCHRONOUS nature of JS.

You can do it.

Thread Thread
officialbidisha profile image
Bidisha Das Author

Can't agree more.

Thread Thread
rickdelpo1 profile image
Rick Delpo

Hey thanks John for ur response. I do agree that I can do it but now comes all the mega time to put in and the learning curve involved. Also I am a bit concerned about all the JS in React impacting my SEO.

Collapse
peacechen profile image
Peace Chen

Plain JS is ok for simple apps, but you'll find yourself buried in a sea of spaghetti code as that app becomes more complex. React and other libraries exist because real-world production apps contain a lot of code that needs good structure and design patterns.

Collapse
rickdelpo1 profile image
Rick Delpo

Can't wait for the spaghetti !! Am not totally giving up on React.
Perhaps this is when I will appreciate React much more.
Thanks for the heads up.
PS: my post is not meant to be a negative rant

Collapse
ryannerd profile image
Ryan Jentzsch

Depending on your use case React (or any framework) can be overkill. I've been developing software for over 25 years and it took me some time to wrap my head around React. I developed mainly using OOP languages such as C#. React favors composition over inheritance and this was very frustrating at first. Keep at it. Eventually you'll get that "ah ha" moment and things will start falling into place.

Collapse
rickdelpo1 profile image
Rick Delpo

Thanks Ryan, then I'm not the only one struggling with React. Good to know. For me it is a real shock coming from 20 years of backend SQL development onto the frontend scene.

Collapse
olamphzy profile image
Olamphzy

I'm also new to React. Would love to learn

Collapse
fayismahmood profile image
fayismahmood

👍👍👍👍👍🔥🔥

Collapse
anshuman_bhardwaj profile image
Anshuman Bhardwaj

well explained @officialbidisha

Collapse
officialbidisha profile image
Bidisha Das Author

Thank you so much.

Collapse
diballesteros profile image
Diego (Relatable Code)

Great write-up. Really excited to see what the future of React is with this update. Probably a ton of interesting new things that can be done by major third-party libraries.

Collapse
officialbidisha profile image
Bidisha Das Author

So am I guessing - the new hooks for third party library integration surely will play a huge role in this. Thanks a ton! 😊

Collapse
nikhilroy2 profile image
Nikhil Chandra Roy

you should make your portfolio responsive, I have gone through your portfolio site, but it's okay, keep up it. Thanks

Collapse
officialbidisha profile image
Bidisha Das Author

Thank you so much! Sure Nikhil. I will surely work on it.

Collapse
andrew_march_b968a4edb028 profile image
Andrew March

Looks like a lil typo in the useSyncExternalStore snippet

Collapse
andrew_march_b968a4edb028 profile image
Andrew March

Or how would
const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot]);
work?

Collapse
jacksonkasi profile image
Jackson Kasi

really thank for share with us :D

Collapse
arzivre profile image
Arzivre

the animation so good

Collapse
officialbidisha profile image
Bidisha Das Author

Thank you! 😊

Collapse
kumarkalyan profile image
Kumar Kalyan

Amazing Content. Beginner Friendly and to the point !

Collapse
officialbidisha profile image
Bidisha Das Author

Thank you, Kumar. 😊

Collapse
adelpro profile image
adelpro

Thinks for you article, nice explanation.
I will add to that the use of and lazy loading.
Its a good combination to use its with useTransition hook to show a seamless user experience.

  • Show animation when the component is loading with "Suspense"
  • Show amination when data is fetching with useTransition.
Collapse
chasm profile image
Charles F. Munat

Sorry, but it's all bullshit. I downloaded the app and went to open it. WTF? I have to sign up to use it? Why? So they can track me, invade my privacy, sell my data?

No serious FOSS app requires you to give away your data to use it. That's not "free" at all -- it's the worst kind of price.

Am I missing something? Is there a way to use it without signing up?

Collapse
picwellwisher12pk profile image
Amir Hameed

I needed one such article. thanks

Collapse
0vortex profile image
TED Vortex (Teodor Eugen Duțulescu)

n1!

Collapse
vareksun profile image
Varek

Thanks for sharing

Collapse
changtimwu profile image
Tim Wu

Is there a project hosted on codesandbox/codepen demostrating all these new features?

Collapse
r11 profile image
Peter Jaffray

Some of this reminds me of the really old "ripscript" from the BBS days in the 90's.

Collapse
pavindulakshan profile image
Pavindu Lakshan

Is there any update in React 18 to support writing error boundaries as functional components? It's a pain to still write error boundaries as class components.

Collapse
wevertoum profile image
Weverton Rodrigues

amazing!!!