What’s new in React 18?
The new version of React is out and it is now available on npm! 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,
- Update dependencies
// for npm
npm install react@18 react-dom@18
//or for yarn
yarn add react@18 react-dom@18
- 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.
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.
-
Without prioritization,
- With concurrency rendering,
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:
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,
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.
And more...
- Check Hybrowlabs for React app development services.
Top comments (0)