Picovert

React 19 Features: Actions, use(), and the New Form Handling Model

2026-04-148 min read

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 useState for isLoading, isError,data
  • Manual try/catch with 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