v19.2 | React
- v19.2 | React
🧩 <Activity />
Problema resolvido
Renderizar partes não visíveis sem roubar prioridade da UI atual.
Exemplo: pré-renderizar uma aba futura
import { Activity, useState } from "react";
function App() {
const [tab, setTab] = useState<"home" | "profile">("home");
return (
<>
<button onClick={() => setTab("home")}>Home</button>
<button onClick={() => setTab("profile")}>Profile</button>
{/* Aba atual */}
<Activity mode="visible">
{tab === "home" && <Home />}
</Activity>
{/* Aba futura, pré-renderizada */}
<Activity mode="hidden">
<Profile />
</Activity>
</>
);
}
📌 O React pode preparar o Profile em background, sem competir com a aba visível.
🔔 useEffectEvent
Problema clássico
Eventos externos + useEffect causam reexecuções desnecessárias.
❌ Antes (problema)
useEffect(() => {
window.addEventListener("resize", () => {
console.log(theme); // força theme nas deps
});
}, [theme]);
✅ Agora (correto)
import { useEffect, useEffectEvent } from "react";
function Component({ theme }) {
const onResize = useEffectEvent(() => {
console.log(theme);
});
useEffect(() => {
window.addEventListener("resize", onResize);
return () => window.removeEventListener("resize", onResize);
}, []);
}
✔ theme atualizado
✔ useEffect não reexecuta
✔ ESLint feliz
✔ Sem closures quebradas
🗃️ cacheSignal (Server Components)
Cenário
Um Server Component começa a trabalhar, mas o cache é invalidado no meio do processo.
Exemplo: abortando trabalho inútil
import { cacheSignal } from "react";
export async function UserData({ id }) {
const signal = cacheSignal();
const data = await fetchUser(id);
if (signal.aborted) {
// trabalho jogado fora
return null;
}
return <pre>{JSON.stringify(data)}</pre>;
}
📌 Útil para:
- queries caras
- agregações grandes
- streaming interrompido
🌐 Pre-renderização parcial (SSR)
Objetivo
Mostrar HTML estático rápido e completar depois.
import { Suspense } from "react";
export default function Page() {
return (
<>
<Header />
<Suspense fallback={<Skeleton />}>
<DynamicSection />
</Suspense>
<Footer />
</>
);
}
✔ Header/Footer renderizam imediatamente ✔ Conteúdo pesado chega depois ✔ SEO preservado
🔄 Agrupamento de Suspense no SSR
Antes
Cada boundary “abria” em tempos diferentes.
Agora
React agrupa revelações para transições mais suaves.
<Suspense fallback={<A />}>
<Suspense fallback={<B />}>
<Content />
</Suspense>
</Suspense>
📌 No SSR:
- menos flicker
- ordem consistente entre servidor e cliente
Nenhuma mudança de código necessária — é comportamento interno.
📊 DevTools — Scheduler & Components
O que você vê agora
- Prioridade de cada render
- Efeitos bloqueando render
- Updates interrompidos
📌 Exemplo de leitura prática:
“Esse componente sempre renderiza como Low Priority, mas está bloqueando um High Priority update.”
Isso não era visível antes.
🧪 useId — prefixo novo
Antes
:r:0
Agora
_r_0
Sem impacto no código:
const id = useId();
<label htmlFor={id}>Nome</label>
<input id={id} />
📌 Evita problemas com:
view-transition-name- XML
- CSS avançado
🧭 Resumo
| Feature | Quando usar |
|---|---|
<Activity /> | Pré-render, abas, navegação |
useEffectEvent | Eventos externos |
cacheSignal | RSC pesados |
| Partial SSR | Performance + SEO |
| Suspense batching | SSR consistente |
| DevTools | Debug real de concorrência |