Some really cool stuff is coming to React! The upcoming release of React 19 is packed with new features designed to boost performance, streamline development, and elevate the overall developer experience.
In this article, I'll highlight features that are expected to be included in React 19, and than focus on two of my favorite ones.
React 19 - Highlights
-
The biggest change is that React 19 will have a Compiler. This means that React will automatically add its own memorization for things like
useMemo
,useCallback
, and thememo
function. (The React team is already using compiler internally and it is powering instagram.com in production!) -
The
use client
anduse server
directives become stable, enabling Frameworks other than Next.js to utilize them. -
Actions are now stable and work on client and server side. React is making it easier to handle life cycle of a form data with hooks like
useFormStatus
anduseFormState
. -
Additional hook that's being added is
useOptimistic
. This hook enables optimistic updates, allowing immediate visual feedback before server processing. For example, if you click on a like button, the like count will increase immediately, and then the server will process the request. If the request fails, the count will be reverted to its original value. -
SEO improvements - Document metadata section: This allows you to put a
title
tag,meta
tag, orlink
tag anywhere inside of your React component and it will be automatically added to the head of the document or wherever it needs to be. -
Suspense: This is a new feature in React 18 that allows you to stream in data to be rendered. React 19 is making improvements to suspense by making sure that it waits for certain things like style tags, links, and scripts to load before the page is rendered.
-
Forward refs: You will no longer need to use
forwardRef
in React 19. Theref
prop will be automatically passed to every component. -
use hook
: This is a new hook that allows you to asynchronously load things, such as JavaScript files, promises, or context.
COMPILER - The best thing in the next big thing
Current state of React - v18
As we all know, React can sometimes re-render too much when state changes. In React 18, one of the ways to optimize performance and avoid unnecessary re-renders is by using the useMemo
hook.
This hook allows you to memoize the result of a function, meaning it will only re-compute the value if the dependencies passed to the hook change.
Example: Let's say you have a component that displays a list of items. Each item has a price, and you want to calculate a discounted price based on a specific discount percentage. This calculation might be expensive if it involves complex logic or API calls.
Here's how you would use useMemo
to avoid re-calculating the discounted price on every render if the items
or discount
prop doesn't change:
function MyComponent({ items, discount }) {
const discountedItems = useMemo(() => {
return items.map(item => ({
...item,
discountedPrice: item.price * (1 - discount),
}));
}, [items, discount]); // Dependency array
return (
<ul>
{discountedItems.map(item => (
<li key={item.id}>
{item.name} - ${item.discountedPrice}
</li>
))}
</ul>
);
}
If we look the other frameworks such as Vue or Svelte, they don’t do stuff like this. For example, in Vue they have computed function, but without dependencies array.
Vue example:
<template>
<ul>
<li v-for="item in discountedItems" :key="item.id">
{{ item.name }} - ${{ item.discountedPrice }}
</li>
</ul>
</template>
<script>
export default {
props: {
items: Array,
discount: Number,
},
computed: {
discountedItems: function () {
return this.items.map(item => ({
...item,
discountedPrice: item.price * (1 - this.discount),
}));
},
},
};
</script>
The reason why these frameworks let us write more simplified code is because they have a compiler, unlike React which is runtime based.
Missing of compile step in react created many performance issues which led to creating hooks like useMemo
and useCallback
to help developers manually handle them.
Now when React gets it’s own Compiler, it means that hooks like useMemo
, useCallback
, or memo
function are thing of the past!
All the memoization and optimization will happen automatically in the background, without the need for developers to manually handle it.
Dealing with PROMISES - The next best thing in the next big thing
In React server components, we can use async/await
to fetch data directly in a component. That's great but we cannot do it in a client side component.
Well, with React 19 we still cannot do that, but what we can do is use a use
hook. use
works with promises and context.
In case of context, this will probably make useContext
hook obsolete. Unlike useContext
, which must be called at the top level of your component, we will be able to use use
even in loops and conditionals.
In case of promises, use
allows us to use value of a resolved promise directly in a UI.
Since a promise is asynchronous and the value is initially pending, we can use Suspense Boundary
to handle loading state and Error Boundary
in case of throwing an error.
const promise = fetch("https://api.example.dev");
export function HomePage({promise }) {
const user = use(promise);
return (
<ErrorBoundary fallback={<p>An error occurred</p>}>
<Suspense fallback={<p> & Downloading... </p>} >
<UserProfile user={user} />
</Suspense>
</ErrorBoundary>
);
}
Conclusion
React 19 is bringing a lot of exciting features that will make our lives as developers easier.
The compiler will take care of memoization and optimization, and the use
hook will allow us to work with promises and context in a more flexible way.
Lot of these features were released in the Canary channel, which is a pre-release channel that tracks the main branch of the React repository. If you want to find out more about React 19, make sure to check out the official blog post.