Description
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
When using ErrorBoundary, component has been rendered twice, even after throwing error during the first render.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
Having simple example:
- Straightforward ErrorBoundary copied from docs;
- Functional component Boom, that throws error on first render;
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: undefined };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
console.log("getDerivedStateFromError", { error });
return { error };
}
componentDidCatch(error, info) {
// You can also log the error to an error reporting service
console.log("componentDidCatch", { error, info });
// this.setState({ error });
}
render() {
console.log("ErrorBoundary.render", this.state.error);
if (this.state.error) {
return "Oops";
}
return this.props.children;
}
}
let boomCounter = 0;
const Boom = () => {
console.log("Boom", ++boomCounter);
throw new Error("Boom");
};
function App() {
return (
<div className="App">
<ErrorBoundary>
<Boom />
</ErrorBoundary>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Boom component has been rendered twice, even after throwing error during the first render.
To make it more clear, I'm logging global counter, increasing with each render :
https://codesandbox.io/s/agitated-lumiere-6zd3h
What is the expected behavior?
Failed component shouldn't be rendered after throwing an error.
Internals of the component can produce side-effects or whatever else, that can be worsen if done twice.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 16.8.6
Browsers: Safari, Chrome.
I have 2 assumptions why is that (I haven't read React core):
- To perform graceful shutdown of useEffect/componentWillUnmount and stuff like that.
- This happens because Boom component provided as external dependency, being rendered in App tree alongside with ErrorBoundary itself. And React perform full render of the App tree, despite ErrorBoundary could have something else to show.
This case is very confusing.
Feel free to close the issue if this behavior is expected, though it should be noted in the documentation.
Ideas of how to get desired behavior are welcome.
I haven't found open problem with this exact behavior described, that's why I created a new one.