Mastering React 19: Enhanced Actions for Better State Management

React 19: Simplify Data Mutations with New Actions Feature

Exploring React 19: Enhanced Actions:

One of the new features in React 19 is the improved handling of actions for data mutations and state updates. When a user action, like form submission, requires an API call, you typically update the state based on the response. Previously, this involved manually managing multiple states such as pending states, errors, and optimistic updates.

Before Actions:

// Before Actions function UpdateName({}) { const [name, setName] = useState(""); const [error, setError] = useState(null); const [isPending, setIsPending] = useState(false); const handleSubmit = async () => { setIsPending(true); const error = await updateName(name); setIsPending(false); if (error) { setError(error); return; } redirect("/path"); }; return ( <div> <input value={name} onChange={(event) => setName(event.target.value)} /> <button onClick={handleSubmit} disabled={isPending}> Update </button> {error && <p>{error}</p>} </div> ); }

In React 19, support is added for using async functions in transitions to handle pending states, errors, forms, and optimistic updates automatically.

// Using pending state from Actions function UpdateName({}) { const [name, setName] = useState(""); const [error, setError] = useState(null); const [isPending, startTransition] = useTransition(); const handleSubmit = () => { startTransition(async () => { const error = await updateName(name); if (error) { setError(error); return; } redirect("/path"); }) }; return ( <div> <input value={name} onChange={(event) => setName(event.target.value)} /> <button onClick={handleSubmit} disabled={isPending}> Update </button> {error && <p>{error}</p>} </div> ); }

The async transition will immediately set the isPending state to true, make the async request(s), and switch isPending to false after any transitions. This ensures that the UI remains responsive and interactive while data is being processed.


By convention, functions that use async transitions are called “Actions”.

Actions handle data submission for you:
  • Pending state: Automatically provides a pending state from the beginning to the end of a request.
  • Optimistic updates: Supports the useOptimistic hook for immediate user feedback during submissions.
  • Error handling: Displays Error Boundaries when a request fails and reverts optimistic updates if necessary.
  • Forms: form elements now support the action and formAction props for automatic form handling and reset after submission.

React 19 introduces useOptimistic for managing optimistic updates and the new React.useActionState hook for common action cases. The form Actions in react-dom manage forms automatically and useFormStatus supports common form-related actions.

Simplified example in React 19:
// Using <form> Actions and useActionState 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 null; }, null, ); return ( <form action={submitAction}> <input type="text" name="name" /> <button type="submit" disabled={isPending}>Update</button> {error && <p>{error}</p>} </form> ); }

Resources