The evolution of React never stops, and the transition from React 17 to React 18 is the latest chapter in this ongoing journey. React 18 promises to take your web development and user experience to a whole new level. As developers, staying up to date with these updates is not just an option; it’s a necessity. In this comprehensive guide, you will learn about React 18’s new features and the benefits it brings to your development projects.
In order to get the most out of this article, you should be familiar with these concepts:
Why keep up with React updates?
React is a constantly changing library, necessitating that developers remain informed and current for the following crucial reasons;
- Enhanced Performance: Staying current allows developers to harness the latest React performance optimizations, ensuring their applications run faster and more efficiently.
- Security Updates: React's evolving nature addresses security vulnerabilities, keeping applications safe from emerging threats and potential risks.
- New Features: Staying updated ensures access to cutting-edge features, empowering developers to create more feature-rich and user-friendly applications.
- Community Support: Being in sync with React's developments means better integration with the thriving React developer community, enabling easier troubleshooting and access to valuable resources.
- Career Relevance: Keeping pace with React's evolution is crucial for career growth, as it demonstrates a commitment to staying competitive in the ever-changing tech industry. Employers often seek developers who are well-versed in the latest tools and technologies.
Evolution of React
React, born from Facebook's quest to simplify web development in 2013, has undergone a transformative journey. React's history reflects its commitment to simplicity and performance. It embraced open-source collaboration in 2013, fostering community involvement and consistent growth.
Notable milestones include React 16 released in 2017, which introduced the groundbreaking Fiber rewrite, and React 17 released in 2020, which paved the way for concurrent mode. Now, the React 18 update released in 2022 takes the stage, building upon this legacy to offer developers an even more potent toolkit for dynamic and responsive web applications.
React 18: What’s New?
The latest React release, React 18, is here. It's different from React 17 in important ways, and it's poised to redefine the user experience, enhance performance, and boost speed. With the React 18 release, you'll find new features that make life easier for developers and users. Let us explore the exciting new features that embody React 18's commitment to fulfilling these promises.
React 18 introduces concurrency, a behind-the-scenes enhancement that significantly improves performance. In contrast to previous versions where updates were synchronous and uninterrupted, React 18 Concurrent mode enables React to switch between tasks. It can start, pause, or even abandon a task, ensuring the user interface remains responsive and maintains a seamless look on the screen.
Moreover, Concurrent React 18 excels at preserving the previous state of the user interface. To simplify, think of a reusable state in Concurrent React as a special kind of memory. When you switch from one part of a website or app to another and then return, it remembers what you were doing before, much like a video game that lets you pick up where you left off.
In the future, a new component called <Offscreen> is anticipated, acting as a helpful assistant for even better memory. This results in web applications loading faster and delivering smoother transitions when navigating between different sections of a site or app.
React 18 New Features
Let's take a closer look at the most significant features of the latest React version. These enhancements are designed to elevate your web development experience and provide you with powerful tools for creating amazing user interfaces.
Batching, in simple terms, means grouping things together to process them at once instead of one by one. In React, this is when multiple state updates are processed together for better performance. This is because processing multiple updates individually can slow down the performance and user experience of a website.
Prior to React 18, updates were only batched in React event handlers, updates inside of Promises, setTimeout, native event handlers, or any other event were not batched in React by default. Here’s an example of how batching works in React Event handlers:
Here’s an example with
From the examples above, you can observe that in the React event handler, React renders only once even though there are multiple updates (Batching!). In contrast, it renders each state update within the setTimeout (No Batching!).
React 18 introduces automatic batching for all state updates, whether they occur within a React event handler, setTimeout, promises, or any other context. You don't need any specific preset hook to get started with automatic batching; once you upgrade to React 18 (more on that later), it activates automatically.
In the example above, state updates within setTimeout in React 18 now render once, regardless of how many state updates occur. React waits to finish all state updates before rendering.You can opt out of automatic batching using a React 18 feature called
flushSync(). This is how it works:
Transition is the process or period of changing from one state or condition to another. In React 18, transitions have been introduced to categorize updates that are not instantaneous and may take some time in the background. This concept classifies updates into two categories:
- Urgent updates: These include actions like typing, clicking, or pressing that require an immediate response.
- Transition or non-urgent updates: These encompass UI transitions that naturally take some time to become visible.
For instance, when fetching data after user input, the user's input event is marked as urgent because the user expects an immediate response. In contrast, fetching results is marked as a transition because it naturally takes some time for the results to be fetched and displayed.
If a transition, like fetching data that takes some time, gets stopped by the user (for example, by typing quickly), React will throw away the old work it was doing and show only the most recent thing you asked for. So, it focuses on what you want now, not what you wanted before.
Transition utilizes concurrency, for instance, if an update in the transition process takes a break, React keeps showing what you were looking at, and in the background, it quietly works on the new stuff for the transition.
You have to call the
useTransition hook at the top of the component where updates would be marked as transitions. This hook returns an array consisting of:
- isPending: A pending value of the previous state.
- startTransition(): A function that allows you to mark state updates as a transition.
New suspense features
Suspense is a feature introduced in React 16 that enables you to define what React should display when a component isn't ready. Initially, Suspense was primarily used in conjunction with React.lazy, which allows components to load only when needed, the suspense is then used to load a fallback (which holds the content of what to be rendered while waiting for the component to load, e.g. spinner) while waiting for the component to render.
Here's how it works:
However, before React 18, Suspense couldn't be used on its own on the server. Now, with React 18, you have the flexibility to use Suspense independently, unlike in the past when it was primarily used alongside React.lazy. This represents one of the significant updates introduced in the Suspense feature in React 18. Additionally, Suspense has been enhanced through concurrency and other new features of React.
Here’s how it works:
When you use Suspense during a transition, such as an animation or data loading, React ensures that the content already on the screen doesn't suddenly vanish, leaving you with a loading message. Instead, React waits until enough data is ready before making changes. This approach eliminates the sudden appearance of a disruptive loading screen, significantly enhancing the user experience during transitions and data loading.
New Client Rendering APIs
The ReactDOM/client APIs assist you in rendering components within a web browser. These APIs include
- createRoot: This method is used to create a root for displaying React 18 components within the browser's DOM. It replaces the `ReactDOM.render` method used in previous versions.
- hydrateRoot: This method is employed to display React components within a browser's DOM node that was previously generated by ReactDOM/server.
Note: To unlock React 18's features, it's essential to use these new APIs as described.
New server-side rendering APIs
Server-side APIs are used to convert React components into HTML on the server and then send them to the client. React has deprecated most of the older APIs, so it's important to make use of these new APIs when working with React. These new APIs are now exported from react-dom/server. They include:
New strict mode
React wants to implement features that preserve the previous state. For example, when you're navigating through website pages, it should remember what you were doing on those previous pages and take you back to that exact point when you return, just like in a game. If you pause a game and resume later, you'll always continue from where you stopped.
To make this happen, React needs to mount and unmount components to preserve their exact state. However, the problem is that some components might encounter errors or issues during this mounting and unmounting process.
Therefore, React has introduced a new strict mode in development-only to test these components by mounting, unmounting and then re-mounting them using the previous state. This helps identify which components have problems and won’t re-mount effectively, it helps you to fix bugs before users report them. Here’s how it works:
Note : There is no way to opt out of strict mode once your component is wrapped in
<StrictMode>, so be assured that all bugs and errors are caught in development.
New React 18 Hooks
React 18 introduced several new hooks, and they include;
- useId : used in generating unique IDs for both client and server.
- usectTransition : used to make updates that are not urgent(as discussed earlier).
- useDefferedValue : used to defer re-rendering of a component without blocking the user interface.
- useInsertionEffect : this is a hook that runs after DOM mutation to help performance issues of updating styles while re-rendering.
- useSyncExternalStore : allows external stores to allow concurrent reads.
React 18 upgrade
To migrate to the latest version of React, you can do that through the following steps:
1. Install react: Navigate to your terminal and run the command as seen below:
2. Update to Client rendering APIs to unlock React 18 Features
Migrate an existing project from React 17 to 18
If you have an existing project in React 17 and you want to migrate to React 18, you can simply do that by:
1. Going into the folder of the project in VS Code and run this command in your terminal
2. Navigating to your
package.json file to confirm that the React version has been updated
3. In your index.js file, replace the import with react-dom/client, and note that the
render method is deprecated in React 18. Replace it with
createRoot. See above for more information.
React 17 vs 18
The React team continuously strives to enhance React as a more efficient front-end development library. React 17 laid the foundation for future React features with some minor enhancements, while React 18 introduced a plethora of new features that significantly enhance optimization and performance. In the following table, we'll explore key differences between React 17 and React 18.
React 18 obviously brought substantial improvements over React 17, making it the version with more significant enhancements.
React 18 styled components
There are three ways to use CSS-in-JS:
- Static extraction to CSS files with a compiler
- Inline styles
- Runtime injection of <style> tags
React recommends using options 1 and 2 if the CSS-in-JS concept is ever needed. This is because using option 3 can cause problems like;
- Runtime injection can lead to multiple recalculations of CSS rules especially in concurrent rendering when different tasks happen at the same time, this can make the web page to be very slow.
- Runtime injection may happen at the wrong time, whereby the layout has already been rendered before styling is applied, making the user see an incomplete screen interface (which is a bad user experience).
React has not figured out how to solve the first problem yet, but the second one has a new solution, which is the React 18 useInsertionEffect hook. This hook helps you to insert styles first before the layout is rendered.
This is how it works:
Note: React doesn't recommend using CSS-in-JS because of the shortcomings previously stated, but if you must use it be sure to do so with the useInsertionEffect.
React 18 Built-in Components
React 18 introduced some new built-in components for your projects. They include:
- <Profiler>: helps you to check for components rendering performance
- <Suspense>: helps you to declare a fallback while the child component loads
- <Strictmode>: helps you to detect bugs early during development
React 18 is a game-changer in frontend development, introducing a lot of amazing features. This guide has explored the evolution and key differences between React 17 and 18, empowering you with a seamless transition.
As you embrace React 18, you're well-equipped to enhance performance and user experience. Continuously explore the thriving React community for resources to stay ahead in this ever-evolving field. Happy coding and remember to keep an eye on our blog for posts on topics that will help you maximize your frontend development and software engineering potential.