⚛️ React 19 New Features
Exploring some of the features of React 19.
React Compiler
React 19 introduces a new compiler, similar in spirit to those in Svelte and Vue. The React Compiler analyzes your components at build time, making React apps faster and automating tedious tasks that previously required manual optimization. This means less boilerplate, fewer bugs, and improved performance out of the box.
Automatic Memoization
Previously, developers had to use useMemo
, useCallback
, and memo
to optimize re-renders and prevent unnecessary computations. Manual memoization can clutter code, is error-prone, and requires ongoing maintenance. With the new compiler, these hooks are no longer necessary—React will handle memoization automatically, reducing cognitive load and making codebases cleaner.
- No more manual
useMemo
,useCallback
, ormemo
in most cases. - The compiler analyzes dependencies and optimizes re-renders for you.
- Legacy hooks still work for backward compatibility.
use()
Hook
The use
hook is a new primitive for reading and asynchronously loading resources such as promises or contexts. Unlike other hooks, use
can be called inside loops and conditionals, making it more flexible and expressive.
use(context)
replacesuseContext(context)
.use(promise)
suspends until the promise resolves and returns its value.- Can be used for data fetching, context, or any resource that supports the "thenable" interface.
Example:
import { use } from 'react'
function MessageComponent({ messagePromise }) {
const message = use(messagePromise)
const theme = use(ThemeContext)
// ...
}
Unlike useContext
, use
can be called in conditionals and loops:
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext)
return <hr className={theme} />
}
return null
}
Like useContext, use(context) always looks for the closest context provider above the component that calls it. It searches upwards and does not consider context providers in the component from which you’re calling use(context).
use client
& use server
Directives
React 19 expands support for server components and directives.
- Use
use client
to mark a file as a client component. - Use
use server
to mark a file or function as a server action or server component.
This enables:
- Improved SEO and initial page load times.
- Direct data fetching and mutation on the server.
- Seamless integration between client and server logic.
Note: You need a Node.js (or Deno, Bun) server to use the
use server
1 directive.
Actions
Actions are a new way to handle form submissions and imperative mutations in React, both on the client and the server.
<form action={search}>
<input name="query" />
<button type="submit">Search</button>
</form>
- Actions can be synchronous or asynchronous.
- Define them on the client with JavaScript or on the server with the
use server
directive. - React manages the data submission lifecycle, providing hooks like useFormStatus and useFormState to access the current state and response.
- Actions are submitted within a transition, keeping the UI responsive.
Example with optimistic UI:
const [state, formAction] = useFormState(reducer, initialState)
<form action={formAction}>
<input name="todo" />
<button type="submit">Add</button>
</form>
useOptimistic
useOptimistic
is a new hook for managing optimistic UI updates. It lets you apply temporary updates to the UI that are automatically reverted or confirmed once the server responds.
- Works with both client and server actions.
- Supports async/await and transitions.
- Great for forms, lists, and any UI where you want to show immediate feedback.
Example:
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo) => [...state, newTodo],
)
function handleAdd(newTodo) {
addOptimisticTodo(newTodo)
// submit to server...
}
Document Metadata
React 19 adds built-in support for managing document metadata such as <title>
, <meta>
, and <link>
tags.
- Works consistently across client-side, SSR, and RSC environments.
- No need for third-party libraries for basic metadata management.
Example:
<title>My Page Title</title>
<meta name="description" content="A description of my page." />
Asset Loading
Suspense
is now integrated with the loading lifecycle of resources such as stylesheets, fonts, and scripts.
- React takes these into account to determine when content is ready to display.
- New Resource Loading APIs like
preload
andpreinit
provide more control over resource loading and initialization. - Improved support for streaming and progressive hydration.
Other Changes & Features
- Refs as Props: You can now pass
ref
as a regular prop, eliminating the need forforwardRef
in many cases. - Improved Web Components Support: Better integration and event handling.
- Simplified Context:
<Context.Provider>
can be replaced with<Context>
for cleaner code. - Concurrent Rendering Improvements: More reliable and predictable concurrent features.
- Better Error Handling: Improved error boundaries and stack traces.
Migration & Compatibility
- Most existing React code will continue to work.
- The compiler is opt-in and will be rolled out gradually.
- Legacy hooks (
useMemo
,useCallback
,memo
) are still supported for backward compatibility. - Some new features (like server actions) require a compatible server environment.