Edit 27th April: React 19 is in Beta! Check out this post to read more.
Support for async functions when handling the following transitions:
Starts at the beginning of a request and automatically resets when final state update is committed
Display Error Boundaries when a request fails and revert optimistic updates to original value
<form>
elements now support functions to action
and formAction
Support for the new useOptimistic
hook to show feedback whilst request are being submitted
…automatically.
function ChangeName({ name, setName }) {
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get("name"));
if (error) {
return error;
}
redirect("/path");
}
);
return (
<form action={submitAction}>
<input type="text" name="name" />
<button type="submit" disabled={isPending}>
Update
</button>
{error && <p>{error}</p>}
</form>
);
}
use
HookRead resources in render. Read a promise and React will suspend until the promise resolves.
import { use } from "react";
function Comments({ commentsPromise }) {
// `use` will suspend until the promise resolves.
const comments = use(commentsPromise);
return comments.map((comment) => <p key={comment.id}>{comment}</p>);
}
function Page({ commentsPromise }) {
// When `use` suspends in Comments,
// this Suspense boundary will be shown.
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
);
}
You cannot use use
when promises are created in render, due to client components.
Another use case for use
is to read Context conditionally.
import { use } from "react";
import ThemeContext from "./ThemeContext";
function Heading({ children }) {
if (children == null) {
return null;
}
// This would not work with useContext
// because of the early return.
const theme = use(ThemeContext);
return <h1 style={{ color: theme.color }}>{children}</h1>;
}
<Context>
No more <Context.Provider>
needed.
const ThemeContext = createContext("");
function App({ children }) {
return <ThemeContext value="dark">{children}</ThemeContext>;
}
This has already been implemented in Next.js (like many of the other features described within this post).
If you have used PHP in the past this may make more sense; putting data on the server and only rendering what’s needed and when it’s needed.
Server actions allow client components to call async functions on the server via use server
. `
The only caveat to using them in React 19 is the following:
While React Server Components in React 19 are stable and will not break between major versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x.To support React Server Components as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement React Server Components in the future.
There is a lot of information flying around about React Server Components, so I’m not going to even try to summarise it here.
ref
No longer need forwardRef
.
function MyInput({ placeholder, ref }) {
return <input placeholder={placeholder} ref={ref} />;
}
//...
<MyInput ref={ref} />;
They’ve finally updated the errors to be more readable! 🎉
Uncaught Error: Hydration failed because the server rendered HTML didn’t match the client. As a result this tree will be regenerated on the client. This can happen if an SSR-ed Client Component used:
- A server/client branch if (typeof window !== 'undefined').
- Variable input such as Date.now() or Math.random() which changes each time it’s called.
- Date formatting in a user’s locale which doesn’t match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
https://react.dev/link/hydration-mismatch
<App>
<span>
+ Client
- Server
at throwOnHydrationMismatch
…
Having heard (unofficially) about React Compiler and memo, and it not being included in this post, I’m intrigued as to what will happen with it.