React 19 traz mudanças radicais na forma de lidar com formulários, transições e data fetching.
useTransition: Agora Automático
No React 18, você marcava transições manualmente:
const [isPending, startTransition] = useTransition();
startTransition(() => {
setPage(2); // Navegação
});
No React 19, navegações são transições por padrão.
use(): Promises Como Hooks
Nova primitive que permite usar Promises diretamente em componentes:
import { use } from 'react';
async function fetchUser(id) {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
function UserProfile({ userPromise }) {
const user = use(userPromise); // ← Suspende automaticamente
return <h1>{user.name}</h1>;
}
// Parent
<Suspense fallback={<Loading />}>
<UserProfile userPromise={fetchUser(123)} />
</Suspense>
Não precisa de async/await no componente. use() resolve a Promise.
Server Actions: POST Sem API Routes
No React 19 + Next.js 14, você pode chamar funções do servidor diretamente:
// app/actions.js
'use server';
export async function createPost(formData) {
const title = formData.get('title');
await db.posts.create({ title });
return { success: true };
}
// app/page.jsx
import { createPost } from './actions';
export default function Page() {
return (
<form action={createPost}>
<input name="title" />
<button>Create</button>
</form>
);
}
Sem fetch(), sem API routes. Só a função.
useOptimistic: UI Otimista
Atualizar a UI antes da resposta do servidor:
import { useOptimistic } from 'react';
function TodoList({ todos }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo) => [...state, { ...newTodo, pending: true }]
);
async function createTodo(formData) {
const title = formData.get('title');
addOptimisticTodo({ id: Date.now(), title });
await fetch('/api/todos', {
method: 'POST',
body: JSON.stringify({ title })
});
}
return (
<form action={createTodo}>
<input name="title" />
<button>Add</button>
<ul>
{optimisticTodos.map(todo => (
<li key={todo.id} style={{ opacity: todo.pending ? 0.5 : 1 }}>
{todo.title}
</li>
))}
</ul>
</form>
);
}
A todo aparece instantaneamente, antes do fetch terminar.
useFormStatus: Estado de Loading
Hook para status de formulários:
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button disabled={pending}>
{pending ? 'Enviando...' : 'Enviar'}
</button>
);
}
function Form() {
async function handleSubmit(formData) {
await fetch('/api/submit', { method: 'POST', body: formData });
}
return (
<form action={handleSubmit}>
<input name="email" />
<SubmitButton />
</form>
);
}
ref Como Prop
Não precisa mais de forwardRef:
// React 18
const Input = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
// React 19
function Input({ ref, ...props }) {
return <input ref={ref} {...props} />;
}
Metadata no Document
Meta tags como componentes:
function BlogPost({ post }) {
return (
<>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
<link rel="canonical" href={post.url} />
<article>{post.content}</article>
</>
);
}
React insere automaticamente no <head>.
Breaking Changes
⚠️ ReactDOM.render() removido (use createRoot())
⚠️ IE11 não suportado
⚠️ propTypes deprecado (use TypeScript)
Conclusão: React 19 é a maior evolução desde Hooks. Server Actions mudam completamente o jogo.