React Error Boundaries
Catch and isolate unexpected runtime JavaScript crashes gracefully using declarative React error boundaries.
TL;DR
- Catch unexpected rendering exceptions gracefully using
errorboundaries. - Display user-friendly fallback interfaces instead of unmounting
blankscreens. - Isolate crashes to individual widgets without destroying entire
applicationtrees.
Class-Based Error Boundary
Derived State From ErrorUpdate component state when render exception occurs.
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}Component Did CatchReport stack trace to telemetry service.
componentDidCatch(
error: Error,
info: React.ErrorInfo
) {
reportErrorToService(error, info.componentStack);
}Conditional Render GuardRender fallback UI if error flag active.
if (this.state.hasError) {
return <FallbackCard error={this.state.error} />;
}
return this.props.children;Using react-error-boundary
Declarative BoundaryWrap unstable components with functional boundary.
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => console.log('Resetting')}
>
<UnstableComponent />
</ErrorBoundary>Fallback Component PropsAccess error details and reset callback.
export function ErrorFallback({
error,
resetErrorBoundary,
}: FallbackProps) {
return (
<CardView>
<CardTitle>Error Occurred</CardTitle>
<Text>{error.message}</Text>
<Button onClick={resetErrorBoundary}>
Retry
</Button>
</CardView>
);
}Reset Keys TriggerAuto-reset boundary when query parameters change.
<ErrorBoundary
resetKeys={[selectedUserId]}
FallbackComponent={ErrorFallback}
>
<UserProfile id={selectedUserId} />
</ErrorBoundary>Error Recovery Strategies
Clear Cache on ResetPurge stale cache keys when retrying failed component.
const onReset = () => {
queryClient.resetQueries();
};Navigation Fallback ButtonProvide route back to safety from error screen.
export function FallbackActions() {
return (
<Button onClick={() => navigate('/')}>
Return Home
</Button>
);
}Granular Widget ResetReset only affected editor without reloading page.
<ErrorBoundary onReset={resetDraft}>
<CommentEditor />
</ErrorBoundary>Error Boundary Boundaries
Widget-Level IsolationPrevent individual chart failures from crashing app.
<DashboardShell>
<ErrorBoundary FallbackComponent={WidgetFallback}>
<StockChart />
</ErrorBoundary>
</DashboardShell>Uncaught Errors FallbackCatch errors that escape all inner boundaries.
// Root boundary for catastrophic failures
<RootErrorBoundary>
<App />
</RootErrorBoundary>Async Error BridgeForward async errors into boundary with useErrorBoundary.
const { showBoundary } = useErrorBoundary();
useEffect(() => {
apiCall().catch(showBoundary);
}, []);Tips
- Place strategic error boundaries like
<ErrorBoundary>around independent features like feeds or comments so an error leaves the rest functional. - Always log captured errors and component stack traces to production monitoring services like Sentry inside
componentDidCatch.
Warnings
- Error boundaries do not catch errors inside asynchronous timers, network fetch callbacks, or native DOM event
handlers. - Failing to provide a recovery reset mechanism leaves users trapped on error fallback screens until they perform a hard page
refresh.
In Practice
Implement a production-grade class error boundary that isolates component crashes and supports interactive recovery.
- Define boundary state tracking error instance and status flag.
- Implement getDerivedStateFromError to switch to fallback UI.
- Send diagnostic reports to telemetry inside componentDidCatch.
- Provide an interactive retry button to attempt re-rendering.
type State = { err: Error | null };
export class Boundary extends Component<any, State> {
state: State = { err: null };
static getDerivedStateFromError(err: Error) {
return { err };
}
render() {
if (this.state.err) {
const reset = () => this.setState({ err: null });
return (
<CardView>
<CardTitle>Error Occurred</CardTitle>
<Button onClick={reset}>Retry</Button>
</CardView>
);
}
return this.props.children;
}
}FAQ
Native React error boundaries must be class components because getDerivedStateFromError and componentDidCatch have no Hook equivalents, though you can use the react-error-boundary library.
Event handlers run outside React's render loop, so exceptions thrown inside them do not affect UI rendering. Use standard try/catch blocks inside event handlers instead.
Provide a reset keys array or trigger a state reset inside the boundary that clears the caught error and attempts to re-render the child component tree cleanly.