A single uncaught error in one component can unmount your entire React tree and leave users staring at a blank screen. Error boundaries fix this by catching rendering errors in a subtree, showing a fallback UI, and keeping the rest of the app alive. They should be part of your component architecture from day one, not bolted on after the first production incident.
Master react error boundaries
Take the React Intermediate course with hands-on lessons and challenges.
A production-ready error boundary that supports static fallback nodes, render-prop fallbacks with access to the error and a reset function, and an onError callback for logging. This single component covers most use cases without any external dependency.
Each dashboard widget gets its own error boundary. If the revenue chart crashes due to malformed API data, the user count and orders table keep working. The Sentry integration sends the React component stack alongside the error, which is critical for debugging -- without it you only get the JavaScript call stack, not which component tree path caused the failure.
The resetKeys prop tells react-error-boundary to automatically clear the error state when the pathname changes. When the user navigates away and comes back, they get a fresh render instead of seeing a stale error. The onReset callback invalidates React Query caches so the retry fetches fresh data rather than replaying the same broken response.
Suspense handles the loading state, the error boundary handles the failure state. The ErrorBoundary wraps Suspense so that a rejected promise (network failure, 500, etc.) gets caught. This is the standard pattern for any async data section in a modern React app -- skipping either half means users see either a blank screen on error or no loading indicator.
Error boundaries normally do not catch event handler errors. The useErrorBoundary hook from react-error-boundary bridges this gap by letting you programmatically push an error into the nearest boundary. This is especially useful for form submissions and other async operations where you want the same fallback UI and logging pipeline that your render errors already go through.
Three levels of boundaries, each with a fallback that matches the scope of what broke. A chart crash shows a small 'Widget unavailable' placeholder. A route-level crash replaces the main content area but keeps the header and footer. An app-level crash is the last resort. Every boundary reports to Sentry, so you know about failures even when users never report them.
Placing a single error boundary at the root and calling it done -- any error in any component shows the same full-page fallback
Use multiple boundaries at different levels: app-level as a catch-all, route-level to isolate pages, and widget-level to isolate independent features. The fallback UI should match the scope of what failed.
Expecting error boundaries to catch event handler errors, async code, or promise rejections -- then wondering why clicks and fetches still crash the app
Error boundaries only catch errors during rendering, lifecycle methods, and constructors. For event handlers and async code, use `try/catch` directly, or use the `useErrorBoundary` hook from `react-error-boundary` to forward those errors into the nearest boundary.
Showing a fallback with no way to recover -- the user is stuck looking at 'Something went wrong' forever
Always provide a recovery path: a retry button that resets the boundary state, a link to navigate away, or automatic reset via `resetKeys` tied to the current route. Combine retry with cache invalidation so the second attempt does not replay the same broken data.
Not logging errors in `componentDidCatch` -- errors are caught and silently swallowed, so the team never finds out about production crashes
Connect `componentDidCatch` (or the `onError` prop in `react-error-boundary`) to your monitoring service. Send the error, the component stack trace, the current URL, and any relevant user context. This is the only way you will know what is actually breaking in production.
Error boundaries catch rendering errors in a React component subtree and display a fallback UI instead of crashing the entire app. They require class components implementing `getDerivedStateFromError` and `componentDidCatch`, though the `react-error-boundary` library provides a much cleaner API. Place boundaries at multiple levels (app, route, widget) for proper isolation, always pair them with Suspense for async data, connect them to error monitoring, and provide retry or navigation options so users are never stuck on a dead screen.
Interactive lessons and challenges on Stanza, practice in VS Code, Cursor, or the web.
Interactive lessons and challenges, right in your code editor.
Check the free courses. No credit card.