React 19.3: View Transitions e Fragment Refs estáveis, e a nova API browser()

O time do React publicou em 9 de setembro de 2026 o post anunciando que “React 19.3 is now available on npm”. É uma versão menor no número, mas não no conteúdo: duas APIs que passaram muito tempo em canary e experimental finalmente viram estáveis, e o react-dom ganha uma forma oficial de tirar um componente da renderização no servidor. Abaixo, o que mudou e o que eu acho que importa no dia a dia.

View Transitions saem do experimental

O componente <ViewTransition> agora é estável. Ele usa a View Transition API do navegador para animar elementos que entram, saem, se movem ou mudam de tamanho. O ponto central do design é que só atualizações marcadas como Transition animam: startTransition, a revelação de um <Suspense> ou uma atualização vinda de useDeferredValue. Atualizações urgentes, como digitar em um input, não disparam animação.

Há quatro tipos de animação (enter, exit, update e share) e props de evento (onEnter, onExit, onShare, onUpdate) para quem quer controlar a animação de forma imperativa. A função addTransitionType permite registrar a causa de uma transição, para que a mesma mudança de estado anime de jeitos diferentes. O exemplo do próprio post é um carrossel:

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

O React também repassa cada tipo ao navegador, então dá para mirar nele no CSS com :active-view-transition-type(...). A integração com Suspense é o detalhe mais interessante: envolver um boundary em <ViewTransition> anima a troca do fallback pelo conteúdo final, e envolver imagens ou fontes faz com que elas suspendam enquanto carregam.

A ressalva importante: por enquanto é só DOM. Segundo o time, React Native e outras plataformas estão em andamento.

Fragment Refs e o FragmentInstance

A segunda API que se estabiliza é a de refs em <Fragment>. Passando um ref para o Fragment, você recebe um FragmentInstance que opera sobre o DOM dos filhos como um grupo, sem adicionar um elemento wrapper. Os métodos cobrem eventos (addEventListener, removeEventListener, dispatchEvent), foco (focus, focusLast, blur), observers (observeUsing para conectar um IntersectionObserver ou ResizeObserver) e medição e rolagem (getClientRects, getRootNode, compareDocumentPosition, scrollIntoView).

Na prática, isso resolve um problema antigo: quantas vezes você colocou uma div extra só para ter onde pendurar um ref ou um observer de visibilidade? Para listas e componentes de layout que não podem ganhar um nó a mais, é uma melhoria real.

browser(), Trusted Types e Context em Server Components

No react-dom, a novidade é browser(). Chamar use(browser()) faz o componente suspender no servidor, então o HTML sai com o fallback do Suspense mais próximo, e no cliente ele não suspende, renderizando normalmente após a hidratação:

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

function Component() {
  use(browser());

  // ...
}

Segundo o post, a chamada pode ser condicional. É a forma oficial de dizer “isso só faz sentido no navegador” sem gambiarras com useEffect e estado de montagem.

Outra mudança de segurança: o React agora passa valores para as APIs do DOM sem convertê-los em string. Isso deixa objetos TrustedHTML, TrustedScript e TrustedScriptURL chegarem intactos ao navegador, então sites com a CSP require-trusted-types-for 'script' passam a funcionar com o React.

Nos Server Components, agora é possível renderizar diretamente um Context importado de um módulo 'use client', sem precisar de um componente Provider intermediário.

Mudanças menores que valem atenção

A lista de “outras mudanças” tem itens que podem afetar apps existentes:

  • Transitions passam a renderizar de forma independente, então uma Transition lenta não segura outras sem relação.
  • Em Strict Mode, efeitos agora são invocados duas vezes também durante a hidratação, igualando o comportamento de raízes renderizadas no cliente. Se você tem efeitos que não toleram dupla execução, isso pode aparecer agora.
  • O react-dom passa a suportar os eventos onFullscreenChange e onFullscreenError, a propriedade SVG maskType e fetchPriority em recursos de módulo.
  • No lado do servidor, o Flight passa a suportar <Activity> e a transportar Error.cause para o cliente.

Há também uma boa lista de correções, incluindo um useDeferredValue que ficava preso em valor antigo e crashes de <ViewTransition> no Safari mobile.

Minha leitura

O React 19.3 é menos sobre novidade e mais sobre consolidação. View Transitions e Fragment Refs estavam sendo experimentadas há bastante tempo; agora dá para usá-las em produção com a garantia de API estável. Para quem usa frameworks, o caminho mais curto até essas features provavelmente vai ser a próxima versão do framework que incluir o 19.3.

Meu conselho prático: antes de atualizar, rode os testes em Strict Mode com atenção à hidratação, porque a dupla invocação de efeitos é o tipo de mudança que expõe bugs latentes. E se você mantém uma CSP com Trusted Types e tinha desistido do React por causa disso, vale reavaliar.

Fontes