Catch Render Errors Before They Break the Whole App
Error Boundaries
An error boundary catches errors during render in its subtree and shows a fallback UI instead. The only place classes still appear.
What you'll learn
- Build a class-based error boundary
- Wrap parts of your app with one
- Recognize what errors boundaries do and don't catch
When a component throws during render, React unmounts the entire tree by default. Production apps wrap risky parts of the tree in error boundaries to show a fallback instead.
Error boundaries are still class components — the only place in
modern React you’ll write one. Or use a library: react-error-boundary.
The Class
import { Component } from "react";
class ErrorBoundary extends Component {
state = { error: null };
static getDerivedStateFromError(error) {
return { error };
}
componentDidCatch(error, info) {
// log to your error tracker
console.error(error, info);
}
render() {
if (this.state.error) {
return this.props.fallback ?? <p>Something went wrong.</p>;
}
return this.props.children;
}
} Use it:
<ErrorBoundary fallback={<ErrorScreen />}>
<Dashboard />
</ErrorBoundary> If anything inside <Dashboard> throws during render, you’ll see
<ErrorScreen /> instead of a blank page.
What Boundaries Catch
- Render errors (
throwin a component, in a hook, in auseMemo) - Errors in lifecycle methods
What they don’t catch:
- Event handlers — wrap with try/catch inside the handler
- Async code — the error is thrown later, outside React’s render
- Server-side render errors (different mechanism)
Where To Put Them
A common strategy: one global boundary at the top (for “the whole app crashed”), plus narrower boundaries around risky widgets:
<App>
<ErrorBoundary fallback={<AppCrash />}>
<Layout>
<ErrorBoundary fallback={<WidgetFallback />}>
<ThirdPartyWidget />
</ErrorBoundary>
<Main />
</Layout>
</ErrorBoundary>
</App> A crash in <ThirdPartyWidget> is contained — the rest of the page
keeps working.
Resetting
Once a boundary catches, its state is “errored”. To recover (e.g.,
let the user try again), give the boundary a way to reset its
state. The react-error-boundary library does this for you with a
resetKeys prop and a <button onClick={resetErrorBoundary}>.
Up Next
A different way to handle “things going wrong” — declarative loading states.
Suspense →