What is error boundary?
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 crashing the entire application. They are a way to gracefully handle errors in the UI.
What is an Error Boundary?
An Error Boundary is a special type of React component that defines a portion of the UI as an error-proof zone. When an unhandled JavaScript error occurs within that zone (i.e., in any of its child components, their lifecycle methods, or their render methods), the Error Boundary catches it. Instead of the entire application breaking, the Error Boundary can render a 'fallback UI' (e.g., an error message) and log the error for debugging purposes.
This mechanism prevents a single component's error from crashing the entire application, improving the user experience by keeping the rest of the application functional.
How to Create an Error Boundary
An Error Boundary is a class component that implements at least one of two lifecycle methods:
- static getDerivedStateFromError(error): This method is called after an error has been thrown by a descendant component. It receives the error that was thrown as a parameter and should return a value to update state, allowing you to render an alternative UI.
- componentDidCatch(error, errorInfo): This method is called after an error has been thrown by a descendant component. It receives the error and an object with componentStack information. It's primarily used for side effects like logging errors.
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error("Uncaught error:", error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
To use it, you wrap a part of your component tree with the Error Boundary component:
<MyErrorBoundary>
<MyProblematicComponent />
</MyErrorBoundary>
Limitations
Error Boundaries only catch errors in the render phase, lifecycle methods, and constructors of the children tree. They do NOT catch errors for:
- Event handlers (e.g., onClick, onChange). Use regular try/catch blocks inside event handlers instead.
- Asynchronous code (e.g., setTimeout, requestAnimationFrame, promises/async/await). Use try/catch within the async code.
- Server-side rendering.
- Errors thrown in the Error Boundary itself (not its children).
Best Practices
- Place Error Boundaries strategically: Wrap critical parts of your application, or individual widgets, to isolate failures.
- Don't over-granularize: Wrapping every component can lead to boilerplate. Balance between protecting essential functionality and maintainability.
- Provide meaningful fallback UI: Inform the user what happened and offer options (e.g., refresh button, contact support).
- Log errors: Always use
componentDidCatchto send errors to an external logging service for proper monitoring and debugging.