Abhinav Anshul
19 Dec 2022
•
4 min read
React Core Team released an alpha version of React18 recently. This release is more focused on User Experience and internal architecture changes, including adaptation to concurrent features.
We can install React 18 right away using:
npm install react@alpha
And ReactDOM,
npm install react-dom@alpha
What's New?
We usually create a Root level DOM level like his and append the React App. This has now been deprecated and is now called "Legacy Root API"
import React from 'react';
import ReactDOM from 'react-dom';
const container = document.getElementById('root')
ReactDOM.render(<App />, container);
Instead, a new Root API
is introduced in React18, which looks like this :
import React from 'react';
import ReactDOM from 'react-dom';
import App from 'App'
const container = document.getEleementById('root')
const root = ReactDOM.createRoot(container)
root.render(<App />)
React18 will ship with both Legacy Root API
and the New Root API
to maintain a smooth transition of React 17(or older) apps to React 18.
Using New Root API over Legacy Root API :
There are quite a few improvements :
a.)Easy to use hydrate function as we can pass an optional boolean value directly to the root.
Legacy Root API :
import ReactDOM from 'react-dom'
import App from 'App'
const container = document.getElementById('app');
ReactDOM.hydrate(<App />, container)
New Root API :
import ReactDOM from ‘react-dom’;
import App from 'App';
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container, { hydrate: true });
root.render(<App />);
Read more about hydration here
b.) Improvements in render callback :
In Legacy Root API, we could pass a render callback function. This is an anonymous function that renders/runs after the root component has been mounted.
import React from 'react';
import ReactDOM from 'react-dom';
import App from 'App'
const container = document.getElementById('root')
ReactDOM.render(<App />, container, function(){
console.log('render only after initial component rendering')
})
console.log('render at very last')
This approach has been changed in New Root API, instead of using callbacks, React Team suggests using requestIdleCallback
or even native setTimeout
This is a new API introduced with this release, which helps in keeping the current webpage responsive and being able to do heavy non-blocking UI updates at the same time.
One important use case for startTransition
could be when a user starts typing in a search box. The input value has to be immediately updated while the search results could wait few milliseconds(as expected by the user).
This API provides a way to differentiate between quick updates and delayed updates. The delayed update(i.e. transition of one UI view to another) is termed as Transition Updates.
For urgent updates like typing, hover, clicking, we call props/functions usually like this :
setText(input)
For non-urgent or heavy UI updates, we can wrap it in a startTransition
API as :
startTransition(() => {
setText(input);
});
React18 will ship <StrictMode />
along with Strict Effects
Mode now. Just like Strict Mode
, this would be for development builds and improved DX.
When a component is wrapped in Strict Effects, React will make sure to "intentionally" run side-effects twice to detect unusual behaviour/pattern, which usually a pain point when working with useEffect
mounting and cleanup functions.
Running effects twice is somewhat like, mount -> unmount -> mount
Server-Side Rendering is getting an architectural overhaul in this release including improvements on first loading screen time. In the trivial version(till React 17), SSR had to load the entire page before it can start hydrating page.
This changes in React18, now we can break React components into smaller chunks using <Suspense />
.
This is now called selective hydration
. suppose we have 4 - 5 different components on the screen, wrapping a component in
<Layout>
<Suspense fallback={<LoadingSpinner />}>
<DelayedComponent />
<Suspense />
<Layout />
Here, the <Delayed />
component won't be resolved until the data is fetched, till then the component will fall back to <LoadingSpinner />
.
We can use <Suspense />
for several components fetching data at different times keeping important components interactive.
Another React 18 concurrent feature, which "orchestrates" the order in which heavy data fetched components appear on the screen.
A <SuspenseList />
takes in revealOrder
prop with values forward, backward or together
<SuspenseList revealOrder="forwards">
<Suspense fallback={<LoadingSpinner />}>
<CardComponent id={1} />
</Suspense>
<Suspense fallback={<LoadingSpinner />}>
<CardComponent id={2} />
</Suspense>
</SuspenseList>
Here the card component will be revealed in a forward direction(until the data is fetched, will fell back to LoadingSpinner Component). Similarly, backwards
will reveal Cards in reverse order, and together prop will render everything "together"
useDeferredValue
takes in a state value, a timeout in milliseconds and returns a "deferred version" of that value. This value lags by the provided timeout seconds.
const deferredValue = useDeferredValue(value, { timeoutMs: 3000 });
This could be a use case for a text input field. The text input would be immediately rendered to the screen however the <CardLists />
text props takes in a useDeferredValue
and returns a defferedText
which lags by 3 seconds. This results in delaying the Card Lists component while still allowing users to have the text field feel snappy.
function App() {
const [text, setText] = useState("");
const deferredText = useDeferredValue(text, { timeoutMs: 2000 });
return (
<div className="App">
<input value={text} onChange={handleChange} />
<CardLists text={deferredText} />
</div>
);
}
React18 has been mostly about concurrent features rather than a full-blown concurrent mode (which has been hyped a lot from React16) reason being the application and libraries author can have a smooth transition and not any breaking changes.
React18 is an alpha release right now and not suitable for production shipping so APIs might evolve until it reaches a stable release by the end of this year(expected). This concludes our post about React18.
Some Important Resources that I have collected over time:
Loved this post? Have a suggestion or just want to say hi? Reach out to me on Twitter
Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ
108 E 16th Street, New York, NY 10003
Join over 111,000 others and get access to exclusive content, job opportunities and more!