Introduction
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.
- Event handlers (learn more)
- Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
- Server side rendering
- Errors thrown in the error boundary itself (rather than its children)
A class component becomes an error boundary if it defines either (or both) of the lifecycle methods static getDerivedStateFromError() or componentDidCatch(). Use static getDerivedStateFromError() to render a fallback UI after an error has been thrown. Use componentDidCatch() to log error information.
class ErrorBoundary extends React.Component {
constructor(props) { super(props); this.state = { hasError: false }; }
// Update state so the next render will show the fallback UI.
static getDerivedStateFromError(error) { return { hasError: true }; }
// You can also log the error to an error reporting service
componentDidCatch(error, errorInfo) { logErrorToMyService(error, errorInfo); }
render() {
if (this.state.hasError) { return <h1>Something went wrong.</h1>; }
return this.props.children;
}
}
/* call as regular React component */
<ErrorBoundary> <MyWidget /> </ErrorBoundary>
How about try/catch?
try/catch is great but it only works for imperative code. However, React components are declarative and specify what should be rendered
try { showButton(); }
catch (error) { ... }
Error boundaries preserve the declarative nature of React, and behave as you would expect.
try/catch can (read, should) be used inside an event handler.