~/blog $ cat react-19-deep-dive.mdx

React 19 Deep Dive: What Changed and Why

·1 min read

$ grep "^##" react-19-deep-dive.mdx13 sections
  1. New React Hooks
  2. └ useActionState
  3. └ useFormStatus
  4. Server Components Improvements
  5. └ Async Components
  6. Performance Enhancements
  7. └ Automatic Batching
  8. Migration Path
  9. └ Step 1: Update Dependencies
  10. └ Step 2: Update Type Definitions
  11. └ Step 3: Migrate Form Handling
  12. Breaking Changes
  13. Conclusion

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!

available for work