Separar espera, falha e dados obsoletos
Uma interface assíncrona não tem apenas dados ou ausência de dados. Pode estar à espera, mostrar um resultado anterior enquanto atualiza, receber uma falha ou receber uma resposta que já não corresponde à seleção. Identifica primeiro o recurso e a tentativa a que cada resultado pertence.
Uma resposta que chegou agora pode ser antiga do ponto de vista da intenção do utilizador. O exemplo recebe reportPromise e attemptId do chamador para tornar essa relação explícita. Não deduz sucesso a partir do desaparecimento de um indicador de carregamento.
O contrato deve dizer que resultado foi aceite, qual falhou e que ação inicia uma nova tentativa.
O que Suspense observa
Suspense fornece um fallback quando conteúdo integrado com o seu mecanismo ainda não está pronto. Entre os casos ensinados aqui estão código carregado através de lazy e leitura de uma Promise com use. Iniciar fetch num Effect ou num handler não ativa automaticamente a boundary.
Se esse fluxo usa estado próprio, precisa de representar carregamento e falha nesse contrato, ou usar uma integração apropriada do framework. O nome de uma variável loading não altera este comportamento. Esta aula limita-se à leitura de dados e código; não depende de funcionalidades experimentais nem dos mecanismos específicos de animação e carregamento de recursos visuais de React 19.3.
Ler uma Promise com identidade estável
use(reportPromise) devolve o valor resolvido, suspende enquanto a Promise está pendente e encaminha a rejeição para o limite de erro apropriado. A Promise precisa de ser conservada em cache para reutilizar a mesma instância entre renders. Criar loadReport(id) em cada render, quando essa função cria sempre uma Promise nova, não cumpre esse contrato.
O chamador do exemplo é responsável pela cache e por novas tentativas. use deve ser chamado no contexto de um componente ou Hook e não deve ser envolvido num try/catch local para substituir o protocolo de suspensão. Quando o valor vem de um Server Component para um Client Component, também existe o requisito de serialização desse valor.
Definir o limite de erro
Uma Error Boundary permite substituir uma subárvore que falhou durante a renderização por uma apresentação de erro. No exemplo, getDerivedStateFromError atualiza estado de forma pura e render escolhe o fallback. componentDidCatch pode acrescentar observação da falha quando necessário.
A boundary não protege erros lançados por si própria e não captura, pelo mesmo mecanismo normal, erros em handlers comuns, callbacks de timers ou renderização do servidor. A documentação distingue a exceção de erros dentro de Actions de transição.
Decide a granularidade pelo produto: um relatório pode falhar sem apagar a navegação que permite escolher outro. Uma boundary em cada elemento pequeno não é automaticamente uma melhor arquitetura.
Resultados de Effects fora de ordem
Noutro desenho, um Effect inicia um pedido quando muda o id. A inicia primeiro, B é selecionado depois, mas B responde antes de A. Aplicar sempre a última resposta a chegar pode mostrar o corpo de A sob o título de B.
O padrão documentado usa um guard local invalidado no cleanup para não aplicar o resultado do Effect anterior. Essa decisão protege a aceitação local; não prova que o transporte ou o trabalho no servidor tenham sido cancelados. O mesmo raciocínio deve abranger sucesso e falha para não mostrar um erro antigo sobre uma seleção nova.
Também é preciso definir o estado apresentado enquanto o pedido atual ainda não terminou.
Recuperação inclui o recurso
Mostrar um fallback é contenção da falha, não uma nova tentativa. Se a cache continua a fornecer a mesma Promise rejeitada, mudar apenas a key da boundary não transforma essa Promise em sucesso. A recuperação deve coordenar a política de cache, a nova tentativa e o reset visual necessário.
No exemplo, attemptId só tem sentido se corresponder à tentativa de recurso fornecida. Evita um botão que apenas repete o erro sem explicar o que mudou. Também distingue recuperar uma leitura de repetir uma escrita: esta aula não estabelece que uma operação externa possa ser repetida sem efeitos adicionais. O contrato deve identificar a operação antes de escolher retry.
Revisão de uma vista assíncrona
Lê a vista em quatro momentos: antes dos dados, com resultado válido, com rejeição e após uma mudança de seleção. Verifica qual boundary trata espera, qual trata erro e que partes da interface continuam disponíveis. Confirma depois a identidade do recurso e a regra de aceitação de respostas.
Uma implementação pode usar mecanismos de dados de um framework sem que React, por si, defina toda a cache ou a política de rede. As avaliações apresentam as premissas necessárias e pedem escolher o próximo comportamento correto. O excerto é uma leitura de contratos de componentes; não exige criar infraestrutura ou executar pedidos para responder.
import {Component, Suspense, use} from 'react';
class ReportErrorBoundary extends Component {
state = {failed: false};
static getDerivedStateFromError() { return {failed: true}; }
render() {
if (this.state.failed) return <p>Report unavailable. Choose a new attempt.</p>;
return this.props.children;
}
}
function ReportBody({reportPromise}) {
const report = use(reportPromise);
return <article><h2>{report.title}</h2><p>{report.summary}</p></article>;
}
// The caller owns caching/retry. Promise identity stays stable per attempt.
// A fulfilled report has string title and summary fields.
export default function ReportPanel({reportPromise, attemptId}) {
return <ReportErrorBoundary key={attemptId}>
<Suspense fallback={<p>Loading report...</p>}>
<ReportBody reportPromise={reportPromise} />
</Suspense>
</ReportErrorBoundary>;
}O chamador fornece uma Promise estável por tentativa. Enquanto está pendente, use integra a leitura com Suspense; se rejeitar, a Error Boundary apresenta a falha. Uma nova tentativa deve fornecer o recurso correspondente e alterar attemptId quando se pretende reinicializar a boundary. O excerto não implementa transporte, cache ou botão de repetição.
Armadilhas comuns
Esperar que Suspense observe qualquer fetch; criar uma Promise por render; capturar use com try/catch; confundir ignorar uma resposta com cancelar o servidor; redefinir apenas a boundary mantendo uma Promise rejeitada.
Tópicos relacionados: Effects, refs e sincronização externa · Desempenho, transições e decisões de renderização · Entrega, hidratação e limites do servidor
A leitura assíncrona precisa de identidade, estado de espera, limite de erro e política de recuperação. Suspense trata leituras integradas; resultados obsoletos e novas tentativas precisam de contratos explícitos.
Referência: Out-of-order Effect results · React 19.3.0; JSX