Error Boundaries
IntermediateWithout a boundary, one thrown error unmounts your entire application and leaves a blank white page. A boundary contains the damage to one part of the screen.
Overview
React deliberately unmounts the whole tree when a render throws, on the grounds that a half-rendered UI can be worse than none — think a banking screen showing the wrong balance. That is only a safe default if you place boundaries, and most apps discover this the first time a null slips into a component and a user reports a completely white page. A boundary catches errors from the components beneath it and renders a fallback instead. Placement is the skill: too high and everything still disappears, too low and every widget needs one.
Writing One
Still a class component — the two lifecycle methods have no hook equivalent.
class ErrorBoundary extends Component {
state = { error: null }
static getDerivedStateFromError(error) {
return { error } // render the fallback
}
componentDidCatch(error, info) {
reportError(error, { componentStack: info.componentStack }) // log it
}
render() {
if (this.state.error) {
return this.props.fallback?.(this.state.error, () => this.setState({ error: null }))
?? <DefaultErrorFallback />
}
return this.props.children
}
}
// react-error-boundary wraps this with a friendlier API, including
// a reset that also resets the subtree:
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => queryClient.resetQueries()}
resetKeys={[location.pathname]} // auto-reset on navigation
>What It Does Not Catch
The list matters, because the gaps are where the blank pages still come from.
// A boundary catches errors thrown during RENDER, in lifecycle
// methods, and in constructors of the tree below it.
// It does NOT catch:
// - event handlers -> try/catch in the handler
// - async code / promises -> .catch, or a query library's error state
// - setTimeout callbacks
// - server-side rendering
// - errors thrown in the boundary itself
async function handleSubmit() {
try { await save() }
catch (e) { setError(e) } // the boundary will never see this
}
// A rejected promise with no handler does not reach a boundary
// either. Catch globally so it is at least reported:
window.addEventListener('unhandledrejection', e => reportError(e.reason))
// Query libraries can rethrow into a boundary if you prefer one
// error path: useQuery({ throwOnError: true })Where to Put Them
Layered, so a failure costs the smallest possible piece of the screen.
// 1. Around the whole app — the last resort, so a crash still
// renders something with a reload option
<ErrorBoundary fallback={<AppCrashed />}><App /></ErrorBoundary>
// 2. Per route — a broken page keeps the header and navigation,
// so the user can go somewhere else
{ path: 'problems', element: <ProblemList />, errorElement: <RouteError /> }
// 3. Around independent widgets — a failing recommendations panel
// must not take down the article the user came to read
<ErrorBoundary fallback={<WidgetUnavailable />}>
<Recommendations />
</ErrorBoundary>
// The fallback should offer a way forward: retry, go back, or
// reload — not just an apology.
// Reset on navigation, or the user is stuck on the error screen
// after moving to a different route.
// Test it: throw deliberately in development and confirm the
// fallback appears where you expect, not two levels up.Key Points to Remember
- 1An uncaught render error unmounts the entire React tree, leaving a blank page
- 2Boundaries are still class components — getDerivedStateFromError renders the fallback, componentDidCatch logs
- 3They do not catch event handlers, async code, timeouts or SSR errors, which need their own handling
- 4Layer them: one around the app, one per route, and one around each independent widget
- 5The fallback must offer a way forward, and boundaries should reset on navigation
Interview Questions
Sign in to ask AriaWhat happens if a React component throws during render and there is no error boundary?
Why do error boundaries not catch errors in event handlers?
Where would you place error boundaries in a typical application?
Ask Aria about Error Boundaries
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.