Skip to main content

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

FeatureQuando usar
<Activity />Pré-render, abas, navegação
useEffectEventEventos externos
cacheSignalRSC pesados
Partial SSRPerformance + SEO
Suspense batchingSSR consistente
DevToolsDebug real de concorrência