Error Boundaries
Error boundaries catch JavaScript errors in their child component tree. They display a fallback UI instead of crashing the entire app.
How They Work
Error boundaries are class components that implement componentDidCatch and static getDerivedStateFromError.
class ErrorBoundary extends React.Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
console.error("Error caught:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h2>Something went wrong.</h2>;
}
return this.props.children;
}
}
Using Error Boundaries
Wrap components that might fail.
function App() {
return (
<ErrorBoundary>
<UserProfile />
<Dashboard />
</ErrorBoundary>
);
}
If either component crashes, the boundary catches it and shows the fallback.
Function Components and Libraries
Function components can’t be error boundaries themselves. Use libraries like react-error-boundary for a hook-based API.
import { ErrorBoundary } from "react-error-boundary";
<ErrorBoundary fallback={<p>Failed to load</p>}>
<RiskyComponent />
</ErrorBoundary>
What They Catch
- Rendering errors
- Lifecycle method errors
- Constructor errors in child trees
What They Don’t Catch
- Event handler errors (use try/catch there)
- Async code (setTimeout, promises)
- Server-side rendering
- Errors in the boundary itself
Best Practices
- Place error boundaries at logical UI boundaries (pages, widgets)
- Provide meaningful fallback UI with a retry option
- Log errors to an external service for monitoring
- Use multiple boundaries to isolate failures
- Combine with try/catch in event handlers
Common Mistakes
- Using error boundaries for event handler errors
- Forgetting to log error details in
componentDidCatch - Showing a blank fallback with no way to recover
- Wrapping the entire app in one boundary (lose granularity)
- Expecting boundaries to catch async errors