React 19 is the first major React version in three years. It ships changes that simplify the most common pain points: form state, async mutations, ref forwarding, and context consumption. Here's what's new and what it replaces.
Actions: the new pattern for async mutations
Actions are async functions that handle form submissions and mutations. React 19 provides hooks that manage the lifecycle of an Action automatically:
function AddToCart({ productId }) { const [state, formAction, isPending] = useActionState( async (prevState, formData) => { const result = await addToCart(formData.get('productId')); return result; }, null ); return ( <form action={formAction}> <input type='hidden' name='productId' value={productId} /> <button disabled={isPending}>Add to Cart</button> </form> ); }
What Actions replace:
- Manual
useStateforisLoading,isError,data - Manual
try/catchwith state updates - Manual
e.preventDefault()
useActionState
The useActionState hook wraps an action function and provides pending state and the last result:
const [state, action, isPending] = useActionState(actionFn, initialState);
useOptimistic
useOptimistic enables optimistic UI updates — showing the expected result immediately while the real request is in flight:
const [optimisticItems, addOptimisticItem] = useOptimistic(items, (state, newItem) => [...state, { ...newItem, pending: true }]);
When the action resolves (or rejects), React automatically reconciles the optimistic state with the real data.
The use() hook
The use() hook reads a value from context or a Promise inside render. Unlike hooks, it can be called conditionally:
// Read a promise (suspends until resolved)
function UserProfile({ userPromise }) { const user = use(userPromise); return <div>{user.name}</div>; }
// Read context (replaces useContext)
const theme = use(ThemeContext);
ref as a prop
React 19 removes the need for forwardRef. You can now pass ref directly as a prop:
// React 19
function Input({ ref, ...props }) { return <input ref={ref} {...props} />; }
<Input ref={myRef} />
// React 18 required forwardRef
const Input = forwardRef((props, ref) => <input ref={ref} {...props} />);
Context as JSX element
React 19 allows using context directly as a JSX element, without the .Provider suffix:
// React 19
<ThemeContext value={theme}>{children}</ThemeContext>
// React 18
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
Improved error handling
React 19 deduplicates hydration errors and provides better error messages with clear component stack traces. The new onCaughtError and onUncaughtError root options give you hooks into error handling without wrapping every component in an error boundary.
Migration
React 19 removes some long-deprecated APIs: defaultProps on function components, legacy Context API (contextTypes, getChildContext), string refs, and ReactDOM.render. Run the React 19 codemod:
npx codemod@latest react/19/migration-recipe