E aí, Dev! O React 19.3 Chegou pra Valer 🚀

Se você acompanhou os experimentos que o time do React soltou ano passado, chegou a hora: o React 19.3 está no npm desde 9 de setembro de 2026 e as APIs experimentais viraram estáveis.

Três coisas brilham nesse release:

  • View Transitions — animações declarativas de entrada, saída, update e share. Agora estável.
  • Fragment Refs — controle de DOM em grupos de irmãos sem precisar de wrapper.
  • browser() — API oficial pra tirar um componente do server rendering.

Tem mais: suporte a Trusted Types (adeus XSS via innerHTML), renderização direta de Context em Server Components e uma penca de bugfixes em Suspense, useDeferredValue e hydration.

Bora ver o que realmente importa. O anúncio completo tá nas release notes oficiais do React 19.3.

React 19.3 View Transitions component mounted in a web app UI showing enter and exit animations Algorithm Concept Visual

View Transitions: Animações Sem Drama

O novo componente <ViewTransition> envolve qualquer parte da sua UI e deixa o React animar usando a View Transition API nativa do browser. O React escolhe o tipo de animação conforme a árvore muda:

  • enter — o componente foi adicionado
  • exit — o componente foi removido
  • update — filhos mudaram de estilo ou conteúdo
  • share — uma transição nomeada se move entre lugares

Só updates dentro de startTransition, useDeferredValue ou de um <ViewTransition> disparam animações. Updates urgentes continuam instantâneos.

import { ViewTransition, useState, startTransition } from 'react';
import { Video } from './Video';
import videos from './data';

export default function Component() {
  const [showItem, setShowItem] = useState(false);

  return (
    <>
      <button
        onClick={() => {
          startTransition(() => {
            setShowItem((prev) => !prev);
          });
        }}
      >
        {showItem ? '➖' : '➕'}
      </button>
      {showItem && (
        <ViewTransition>
          <Video />
        </ViewTransition>
      )}
    </>
  );
}

Controle Fino com addTransitionType

Mesmo state update, animações diferentes? É pra isso que serve o addTransitionType. Navegar um carrossel pra frente e pra trás mexe no mesmo currentSlide, mas você quer animações opostas:

function nextSlide() {
  startTransition(() => {
    addTransitionType('next');
    setCurrentSlide(c => c + 1);
  });
}

function previousSlide() {
  startTransition(() => {
    addTransitionType('previous');
    setCurrentSlide(c => c - 1);
  });
}

O React também expõe esses tipos como view transition types do browser, então você pode mirar no CSS com :active-view-transition-type(next).

Integração com Suspense

Aqui é onde fica interessante. Envolver um Suspense boundary em <ViewTransition> deixa o React animar a transição fallback → conteúdo final. Mas atenção: conteúdo em cache que resolve instantaneamente também vai animar, e isso deixa a app lenta. A regra do time do React:

  • Fallbacks aparecem imediatamente, sem animação
  • Fallback → conteúdo final anima
  • Filhos que não suspendem aparecem imediatamente, sem animação

Dá pra forçar isso desabilitando todas as animações exceto update. Veja a doc de animações com Suspense pro padrão completo.

Developer coding React 19.3 Fragment Refs example on a laptop with browser DevTools open Coding Session Visual

Fragment Refs: Controle de DOM Sem Wrapper

Já precisou colocar um ref num componente que renderiza um monte de irmãos sem pai único? Ou num componente de terceiros que não faz forward de ref? Fragment Refs resolvem exatamente isso.

function Component() {
  const fragmentRef = useRef(null);

  useEffect(() => {
    const fragmentInstance = fragmentRef.current;
    fragmentInstance.focus();
  }, []);

  return (
    <Fragment ref={fragmentRef}>
      {posts.map(post => (
        <article key={post.id}>{post.title}</article>
      ))}
    </Fragment>
  );
}

O FragmentInstance te dá um subconjunto curado de métodos DOM que operam no grupo sem mexer na estrutura:

MétodoPra quê serve
addEventListener / removeEventListener / dispatchEventEventos nos filhos de primeiro nível
focus / focusLast / blurNavegação de foco em profundidade
observeUsing / unobserveUsingConectar IntersectionObserver ou ResizeObserver
getClientRects / getRootNode / compareDocumentPosition / scrollIntoViewMedição e scroll

browser(): Sair do SSR Sem Gambiarra

Server rendering não consegue gerar HTML útil pra componentes que dependem de localStorage, timezone do Intl ou outras APIs só do browser. O jeito antigo era um flag mounted em useEffect ou checar typeof window !== 'undefined'.

O React 19.3 traz use(browser()):

import { use } from 'react';
import { browser } from 'react-dom';

function TimeZone() {
  use(browser());
  const timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
  return <span>{timeZone}</span>;
}

No servidor, isso suspende e mostra o Suspense fallback mais próximo. No cliente, resolve na hora. Pode ser chamado condicionalmente — ótimo pra hooks de fetch que só devem rodar no cliente quando não recebem initialData.

Trusted Types e Server Components

Duas adições importantes:

  • Suporte a Trusted Types — o React agora passa objetos TrustedHTML, TrustedScript e TrustedScriptURL sem coagir pra string, então sua policy CSP require-trusted-types-for 'script' funciona de verdade.
  • Context em Server Components — Server Components agora podem importar e renderizar Context direto de um módulo 'use client'. Adeus componentes Provider que só repassavam prop.
// user-context.js
'use client';
import { createContext } from 'react';
export const UserContext = createContext(null);

// server-component.js
import { UserContext } from './user-context';

export async function Layout({ children }) {
  const currentUser = await getCurrentUser();
  return (
    <UserContext.Provider value={currentUser}>
      {children}
    </UserContext.Provider>
  );
}

⚠️ Cuidados e Limitações

  • View Transitions são só DOM por enquanto. React Native tá em desenvolvimento, mas não saiu. Não arquitete em cima disso se for cross-platform.
  • Exagerar em animações com Suspense dá tiro no pé. O próprio time do React avisa: animar conteúdo em cache deixa a app mais lenta, não mais fluida.
  • browser() não é estratégia de fetch. É escape hatch de renderização. Combine com cache de verdade ou vai refazer fetch a cada mount.
  • React 19.3 é minor. Se você ainda tá no 18.x, a superfície de migração é bem maior do que esse changelog sugere.

React 19.3 release overview on a laptop screen showing npm install react@19.3 terminal output Developer Related Image

Próximos Passos

Se você já tá no React 19.x, o upgrade é tranquilo. Comece pelo mais fácil:

  1. Troque flags mounted por use(browser()) onde fizer sentido.
  2. Teste Fragment Refs em listas que hoje usam <div> só pra segurar ref.
  3. Prototipe View Transitions em modal ou carrossel — é onde o ganho aparece mais.
  4. Audite animações de Suspense — desabilite tudo exceto update a menos que tenha motivo específico.

Se você ainda tá no React 18, esse release sozinho não justifica migrar. Junte com o upgrade geral pro React 19 e planeje a história de Server Components se estiver usando framework tipo Next.js.

Pra contexto arquitetural mais profundo sobre como times grandes entregam mudanças de config e comportamento com segurança — a mesma disciplina que se aplica a espalhar View Transitions por um design system — dá uma olhada no nosso deep dive sobre como a Airbnb entrega mudanças dinâmicas de config em escala. E se você quer pensar em como o usuário percebe essas animações novas, vale ler sobre a década de evolução em psicologia de produto — porque uma View Transition é decisão de UX, não só técnica.

Este conteúdo foi elaborado com o auxílio de ferramentas de IA, com base em fontes confiáveis, e revisado pela nossa equipe editorial antes da publicação. Não substitui o aconselhamento de um profissional especializado.