React 19: What Actually Matters
React 19 shipped with Server Components, Actions, and the new use() hook. Here's an honest take on which features will change how you write code day-to-day.
React 19 has been in the works for years and the changelog is long. After spending a few weeks building with the stable release, here's what's actually worth your attention.
Actions and useActionState
This is the one that changes daily development the most. React Actions are async functions you can pass directly to form action props, and useActionState gives you a clean way to manage their loading and error state.
async function submitForm(prevState: State, formData: FormData) {
const name = formData.get('name')
await saveToDatabase(name)
return { success: true }
}
function MyForm() {
const [state, action, isPending] = useActionState(submitForm, null)
return (
<form action={action}>
<input name="name" />
<button disabled={isPending}>
{isPending ? 'Saving...' : 'Save'}
</button>
</form>
)
}
No more manual useState + useEffect + loading flags for simple form submissions. This alone is worth the upgrade.
The use() hook
use() lets you read a Promise or Context inside a component during render — it suspends automatically if the Promise hasn't resolved yet.
function UserCard({ userPromise }: { userPromise: Promise<User> }) {
const user = use(userPromise) // suspends until resolved
return <div>{user.name}</div>
}
It's composable in ways that useContext isn't — you can call it inside conditionals and loops.
What I'm less excited about
Server Components are real and powerful, but they require a compatible framework (Next.js App Router, or TanStack Start's upcoming RSC support). For most teams, adopting RSC means a significant architecture shift. I'd wait until the tooling matures more before jumping in on a production app.
Verdict
Upgrade for Actions and useActionState — they solve a real, recurring pain point. Server Components are compelling but not urgent unless your framework is already set up for them.