Error Boundaries
These docs are old and won’t be updated. Go to react.dev for the new React docs.
These new documentation pages teach modern React:
No passado, erros de JavaScript dentro de componentes costumavam corromper o estado interno do React e fazê-lo emitir erros incompreensíveis nas próximas renderizações. Estes erros eram causados por um erro anterior no código da aplicação, mas o React não fornecia um meio para tratá-los de forma graciosa nos componentes e não conseguia se recuperar deles.
Introduzindo Error Boundaries
Um erro de JavaScript em uma parte da UI não deve quebrar toda a aplicação. Para resolver este problema para usuários do React, o React 16 introduziu um novo conceito de “error boundary”.
Error boundaries são componentes React que capturam erros de JavaScript em qualquer lugar na sua árvore de componentes filhos, registram esses erros e mostram uma UI alternativa em vez da árvore de componentes que quebrou. Error boundaries capturam estes erros durante a renderização, em métodos do ciclo de vida, e em construtores de toda a árvore abaixo delas.
Nota
Error boundaries não capturam erros em:
- Manipuladores de evento (saiba mais)
- Código assíncrono (ex. callbacks de
setTimeout
ourequestAnimationFrame
)- Renderização no servidor
- Erros lançados na própria error boundary (ao invés de em seus filhos)
Um componente de classe se torna uma error boundary se ele definir um (ou ambos) dos métodos do ciclo de vida static getDerivedStateFromError()
ou componentDidCatch()
. Use static getDerivedStateFromError()
para renderizar uma UI alternativa após o erro ter sido lançado. Use componentDidCatch()
para registrar informações do erro.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) { // Atualiza o state para que a próxima renderização mostre a UI alternativa. return { hasError: true }; }
componentDidCatch(error, errorInfo) { // Você também pode registrar o erro em um serviço de relatórios de erro logErrorToMyService(error, errorInfo); }
render() {
if (this.state.hasError) { // Você pode renderizar qualquer UI alternativa return <h1>Algo deu errado.</h1>; }
return this.props.children;
}
}
E então você pode usá-la como um componente qualquer:
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
Error boundaries funcionam como o bloco catch {}
do JavaScript, mas para componentes. Apenas componentes de classe podem ser error boundaries. Na prática, na maioria das vezes você irá declarar um componente error boundary uma vez e usá-lo em toda a aplicação.
Note que as error boundaries apenas capturam erros nos componentes abaixo delas na árvore. Uma error boundary não pode capturar um erro em si mesma. Se uma error boundary falhar ao tentar renderizar a mensagem de erro, o erro será propagado para a error boundary mais próxima acima dela. Isto também é parecido com a forma que o bloco catch {}
funciona no JavaScript.
Demonstração ao vivo
Veja este exemplo de como declarar e usar uma error boundary.
Onde colocar error boundaries
Você é quem decide a granularidade das errors boundaries. Você pode envolver componentes da rota superior para exibir uma mensagem como “Algo deu errado” para o usuário, da mesma forma que frameworks server-side costumam lidar com travamentos. Você também pode envolver widgets individuais em uma error boundary para protegê-los de quebrar o restante da aplicação.
Novo comportamento para erros não tratados
Esta alteração tem uma implicação importante. A partir do React 16, erros que não forem tratados por uma error boundary irão fazer com que toda a árvore de componentes React seja desmontada.
Nós debatemos esta decisão, mas em nossa experiência é pior deixar uma UI corrompida ser exibida do que removê-la completamente. Por exemplo, em um produto como o Messenger, deixar a UI quebrada visível poderia fazer com que alguém envie uma mensagem para a pessoa errada. Do mesmo modo, é pior para um app de pagamentos exibir um valor errado do que não renderizar nada.
Esta alteração significa que quando você migrar para o React 16, você provavelmente irá descobrir alguns travamentos existentes em sua aplicação que antes passavam despercebidos. Adicionar errors boundaries permite que você forneça uma experiência de usuário melhor quando algo der errado.
Por exemplo, o Facebook Messenger envolve o conteúdo da barra lateral, do painel de informações, do histórico da conversa e do input de mensagem em error boundaries separadas. Se algum componente em uma destas áreas da UI quebrar, o restante continua funcionando.
Nós também encorajamos que você use serviços de relatório de erros JS (ou faça o seu próprio) para que você possa ficar sabendo sobre exceções não tratadas quando elas acontecerem em produção e consertá-las.
Stack traces de componentes
O React 16 registra todos os erros ocorridos durante a renderização no console em desenvolvimento, mesmo que a aplicação absorva-os acidentalmente. Além da mensagem de erro e a stack do JavaScript, ele também fornece as stack traces do componente. Agora você pode ver onde exatamente na árvore de componentes a falha aconteceu: