React 19 landed in December 2024 as a stable release after the longest beta period in the library's history. It brings fundamental changes to how React works under the hood — changes that affect performance, server rendering, form handling, and even how you think about state. But if you're just starting to learn React, none of that should frighten you. Let's break down what's new, what matters, and what to actually learn first.
React 19 Is Here: The Key Changes
React 19 is the most significant major release since React 16 introduced Hooks in 2018. The headline changes are:
- The React Compiler (formerly "React Forget") — automatic memoisation
- First-class support for async transitions via Actions
- New hooks:
use(),useFormStatus(),useFormState(),useOptimistic() - Server Components as a stable, first-party concept
- Improved
refhandling — refs can now be passed as props withoutforwardRef - Improved hydration error messages (finally)
React Compiler: What It Means for Performance
This is the biggest architectural change. Today, React re-renders components when state changes — and as an optimisation, developers manually wrap expensive computations in useMemo() and functions in useCallback(). This is tedious, error-prone, and clutters code.
The React Compiler automatically analyses your components at build time and adds the necessary memoisation — no manual useMemo required. This means:
- Fewer unnecessary re-renders by default
- Cleaner code — remove most existing
useMemoanduseCallbackcalls - Performance improvements without developer overhead
// Before React Compiler — you had to manually memoize
function ExpensiveList({ items, filter }) {
const filtered = useMemo(
() => items.filter(item => item.category === filter),
[items, filter]
);
return <ul>{filtered.map(i => <li key={i.id}>{i.name}</li>)}</ul>;
}
// With React Compiler — just write the logic, compiler handles it
function ExpensiveList({ items, filter }) {
const filtered = items.filter(item => item.category === filter);
return <ul>{filtered.map(i => <li key={i.id}>{i.name}</li>)}</ul>;
}
Server Components and When to Use Them
React Server Components (RSC) run on the server and send HTML to the client — they never ship JavaScript to the browser. This sounds simple but has big implications: you can fetch data, read databases, and access the filesystem directly inside a component without any useEffect or API layer.
Use Server Components for:
- Components that fetch data (blog post content, user dashboard data)
- Large dependencies that shouldn't ship to the client (heavy markdown parsers, DB drivers)
- Layouts and pages where you don't need interactivity
Keep Client Components for:
- Anything that uses
useState,useEffect, or browser APIs - Interactive elements: buttons, forms, modals, live search
- Third-party components that rely on client-side state
// Server Component — runs only on server, can fetch data directly
async function BlogPost({ id }) {
const post = await fetchPostFromDB(id); // direct DB access, no API needed
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
<LikeButton postId={id} /> {/* Client Component for interactivity */}
</article>
);
}
New Hooks: use(), useFormStatus(), and useFormState()
React 19 introduces several new hooks that solve common patterns with less boilerplate:
use()
The use() hook lets you read the value of a Promise or Context inside a component. Unlike useEffect, it can be called conditionally and works with Suspense for loading states.
import { use, Suspense } from 'react';
function UserProfile({ userPromise }) {
const user = use(userPromise); // suspends until promise resolves
return <div>{user.name}</div>;
}
// Wrap with Suspense for loading state
<Suspense fallback={<Spinner />}>
<UserProfile userPromise={fetchUser(id)} />
</Suspense>
useFormStatus() and useFormState()
These hooks make form handling dramatically simpler. useFormStatus() tells a child component about its parent form's submission state — no prop drilling required. useFormState() manages form state in response to server actions.
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button disabled={pending}>
{pending ? 'Submitting...' : 'Submit'}
</button>
);
}
Actions and Async Transitions
React 19 formalises the concept of "Actions" — async functions that handle state transitions, including pending states, errors, and optimistic updates. You can pass async functions directly to the action prop of a form.
async function createTodo(formData) {
'use server'; // Server Action in Next.js
const title = formData.get('title');
await db.todos.create({ title });
}
export default function TodoForm() {
return (
<form action={createTodo}>
<input name="title" />
<SubmitButton />
</form>
);
}
What Beginners Should Still Learn First
All of the above is exciting, but if you're new to React, the fundamentals haven't changed. Learn these in order:
- JSX — what it is, how it compiles, expressions in curly braces
- Components — functions that return JSX, props, and composing components
- State with useState — local state, re-rendering, state updates
- Event handling — onClick, onChange, onSubmit
- Lists and keys — rendering arrays with .map(), why keys matter
- useEffect — side effects, cleanup, dependency array
- Lifting state up — sharing state between components
The Ecosystem in 2025: Next.js vs Remix vs TanStack Start
Once you know React basics, you'll need a framework for routing, server rendering, and deployment. Here's how the options compare:
- Next.js 15 — still the market leader. Best ecosystem, most employers use it, best documentation. Use this unless you have a specific reason not to. App Router + Server Components are the default.
- Remix — excellent data loading model (loaders and actions), web standards focused. Great choice for data-heavy apps. Now merged with React Router v7, which changes the picture significantly.
- TanStack Start — new entrant backed by the TanStack ecosystem (React Query, React Table). Type-safe file-based routing. Worth watching but ecosystem is still young.
Build Real Web Apps With React and Next.js
Our Web Development course covers React from the ground up through to deploying full-stack Next.js applications — with real projects at every step.
View the Web Development Course →