React 19: What's Actually New
React 19 has been in the works for a long time, and the final release delivered several features that meaningfully change how we write components.
Actions
The biggest addition is Actions — a first-class way to handle async mutations. Any async function passed to a transition becomes an Action:
function UpdateNameForm() {
const [error, submitAction, isPending] = useActionState(
async (prevState: string, formData: FormData) => {
const error = await updateName(formData.get('name') as string)
if (error) return error
redirect('/profile')
},
null,
)
return (
<form action={submitAction}>
<input name="name" />
{error && <p>{error}</p>}
<button disabled={isPending}>Save</button>
</form>
)
}
No more manual useState for loading states and error handling around form submissions.
The use() Hook
use() lets you read a resource — a Promise or Context — inside the render function. Most usefully, it composes with Suspense:
function Message({ messagePromise }: { messagePromise: Promise<string> }) {
const message = use(messagePromise)
return <p>{message}</p>
}
useOptimistic
For instant UI feedback before a server response, useOptimistic makes optimistic updates trivial to implement and automatically rolls back on error.
Upgrading
The React 19 upgrade guide is thorough. The main breaking changes are around legacy refs and the removal of some deprecated APIs. For new projects, just start with 19 — there's no reason to reach for 18.