React 19 Actions and async transitions represent the most significant change to React's data mutation model since hooks — eliminating the manual loading, error, and optimistic update state management that made forms and server interactions complex to implement correctly. This comprehensive guide covers every new React 19 API: Actions, useActionState, useFormStatus, useOptimistic, use(), and the server functions model — with production patterns for enterprise application development.
React 19 Actions: The Core Change
useState and useEffect. React 19 introduces Actions — async functions passed to transition-aware APIs that React automatically manages for loading state, error handling, and optimistic updates. An Action is any async function that handles a data mutation. The new hooks (useActionState, useFormStatus, useOptimistic) compose around Actions to provide complete form and mutation state management with dramatically less code.New APIs Reference
| API | Purpose | Key Behaviour |
|---|---|---|
| useActionState | Manage state derived from an async action — loading, error, result | Returns [state, dispatch, isPending]; action updates state on resolution |
| useFormStatus | Access status of the parent <form> submission in any child component | Must be in a component rendered inside a form; returns {pending, data, method} |
| useOptimistic | Show optimistic state while an async action is in-flight | Accepts optimistic update function; reverts automatically on action failure |
| use() | Read a Promise or Context value inside render — suspends if needed | Can be called conditionally; works with any Promise or Context |
| Server Functions | Async functions that run exclusively on the server, callable from client | 'use server' directive; automatically serialised; available as Actions |
useActionState in Practice
action prop of <form> — React calls it with FormData on submit and manages the pending state. Use useFormStatus in child components (like a submit button) to access pending state without prop-drilling. The form automatically resets after successful submission. This replaces the preventDefault + fetch + state management pattern from React 18 with a few lines of clean declarative code.'use server' to make it a server function — callable from client components but running exclusively on the server with full database access. In Next.js App Router, server functions replace most API route handlers for mutations. Provides type safety end-to-end without an explicit REST API layer. Dramatically simplifies the client-server boundary for enterprise Next.js applications.use() hook reads a Promise value in render — suspending the component until the Promise resolves. Unlike useEffect fetching, use() works with React's Suspense model for proper loading state composition. Pass a Promise from a parent server component to a client component — the client component uses use(promise) to stream in the value as it resolves, enabling progressive rendering patterns in enterprise applications.Migration from React 18
React 19 requires createRoot — if you're still on ReactDOM.render, this is a prerequisite migration. Upgrade to React 19: npm install react@19 react-dom@19. React 19 removes some legacy lifecycle warnings — run your test suite and address any deprecation warnings first. Most React 18 apps migrate with zero code changes beyond the version bump. Our software development team handles complex React migrations.
Identify your highest-complexity form components — those with the most loading/error/success state management. Migrate these to useActionState first — the code reduction is most dramatic for complex forms. New forms should be written with Actions from the start. Do not force-migrate all forms at once — prioritise by complexity and developer pain. Connect to your CI/CD pipeline for incremental deployment.
Our software development team provides React 19 migration support and builds new enterprise applications using React 19's Actions model with Next.js 15. Book a free advisory session.