Actualmente estoy siguiendo junto con la documentación de React JS y he encontrado un problema con los límites de error que no funcionan como se esperaba. He intentado replicar el ejemplo que se muestra en el CodePen proporcionado por los documentos, y algunos otros ejemplos simples que he encontrado en Internet, sin embargo, no funciona igual para mí que en la demostración y estoy luchando para entender por qué.
El problema exacto es que el error se produce dos veces porque el componente BuggyCounter se procesa un tiempo adicional. No entiendo por qué el componente está desgarrando por segunda vez.
Por favor, eche un vistazo a este ejemplo mínimo.
import React, { Component } from 'react';
function App() {
return (
<ErrorHandler>
<BuggyCounter />
</ErrorHandler>
);
}
class ErrorHandler extends Component {
constructor(props) {
super(props);
this.state = {
error: false,
errorInfo: null
}
}
componentDidCatch(error, errorInfo) {
this.setState({ error, errorInfo });
}
render() {
console.log('rendering ErrorHandler. ' + (this.state.error ? "error" : "no error"));
if(this.state.error) {
return <p>Error</p>
}
return this.props.children;
}
}
class BuggyCounter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
}
handleClick = () => {
this.setState(({ counter }) => ({
counter: counter + 1
}));
};
render() {
console.log('rendering BuggyCounter. count: ' + this.state.counter);
if (this.state.counter === 5) {
throw new Error('I crashed!');
}
return <h1 onClick={this.handleClick}>{this.state.counter}</h1>
}
}
export default App;
El componente BuggyCounter se está reemplazando con la <p>
etiqueta que muestra "Error" (que es el efecto deseado), pero solo por un momento. Inmediatamente después de eso, se muestra la página de error predeterminada, lo que anula el propósito de los límites de error.
Aquí está mi consola:
Agradecería cualquier información que pudiera proporcionar sobre este tema.
Resolución temporal:
No es una respuesta a mi pregunta, pero una forma de evitar el renderizado redundante es arrojar el error en componentDidUpdate
lugar de hacerlo render
.
render() {
console.log('rendering BuggyCounter. count: ' + this.state.counter);
return <h1 onClick={this.handleClick}>{this.state.counter}</h1>
}
componentDidUpdate() {
if(this.state.counter === 5)
throw new Error('I crashed');
}
componentDidCatch
verá que arroja el error dos veces, pero solo pasa componenDidCatch
una vez.