React 19 Deep Dive: What Changed and Why

January 8, 2026

React 19 Deep Dive: What Changed and Why

React 19 brings significant improvements to how we build applications. After upgrading several projects, I've compiled a comprehensive guide to the most impactful changes.

New React Hooks

useActionState

Simplify form handling with the new useActionState hook:

import { useActionState } from 'react'; function LoginForm() { const [state, action, isPending] = useActionState(async (prev, form) => { const result = await login(form.get('username'), form.get('password')); return result; }, null); return ( <form action={action}> <input name="username" type="text" /> <input name="password" type="password" /> <button disabled={isPending}> {isPending ? 'Logging in...' : 'Log in'} </button> {state?.error && <p>{state.error}</p>} </form> ); }

useFormStatus

Get form submission status without prop drilling:

import { useFormStatus } from 'react-dom'; function SubmitButton() { const { pending } = useFormStatus(); return ( <button disabled={pending}> {pending ? 'Submitting...' : 'Submit'} </button> ); }

Server Components Improvements

Async Components

Server components now support async operations naturally:

async function UserProfile({ userId }: { userId: string }) { const user = await db.query.users.findOne({ id: userId }); const posts = await db.query.posts.findMany({ userId }); return ( <div> <h1>{user.name}</h1> <ul> {posts.map(post => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }

Performance Enhancements

Automatic Batching

React 19 automatically batches all state updates, even in async operations:

function Counter() { const [count, setCount] = useState(0); const handleClick = async () => { // Both updates are batched into a single render setCount(c => c + 1); setCount(c => c + 1); await someAsyncOperation(); // These are also batched setCount(c => c + 1); setCount(c => c + 1); }; return <button onClick={handleClick}>{count}</button>; }

Migration Path

Step 1: Update Dependencies

npm install react@19 react-dom@19

Step 2: Update Type Definitions

npm install --save-dev @types/react@19 @types/react-dom@19

Step 3: Migrate Form Handling

Replace form submission handlers with Server Actions and useActionState.

Breaking Changes

  • Automatic ref forwarding is now the default
  • Context as providers syntax has changed slightly
  • Some legacy APIs have been deprecated

Conclusion

React 19 is a substantial upgrade that makes building complex applications easier and more efficient. The improvements to forms, server components, and performance are worth the migration effort.

Have you upgraded to React 19 yet? Share your experience!

GitHub
X