Error Boundaries
Class components that catch render/lifecycle errors in children and show a fallback UI instead of crashing.
🧑🏫 Sabse pehle — simple mein samjho#
Ghar mein MCB/fuse kyun lagate hain? Taaki agar ek room ka wiring short ho jaaye, toh poore ghar ki light band na ho — sirf woh ek line trip ho. React mein Error Boundary bilkul MCB jaisa hai: agar app ka ek component crash ho jaaye, toh poori app white screen na dikhaye. Error boundary us error ko pakad leta hai aur uski jagah ek friendly fallback UI dikha deta hai — jaise "Kuch galat ho gaya, dobara try karo". Baaki app normal chalti rehti hai.
// Boundary ke andar wala component crash ho toh...
<ErrorBoundary fallback={<p>Kuch galat ho gaya 😔</p>}>
<Profile /> {/* agar yeh phat gaya... */}
</ErrorBoundary>
{/* ...toh sirf fallback dikhega, poori app safe rahegi */}
Yaad rakho: Error boundary = MCB — ek component crash ho toh poori app band na ho, fallback UI dikhe.
The core idea#
An error boundary is a component that catches JavaScript errors thrown during rendering, in lifecycle methods, or in constructors of its child tree, logs them, and renders a fallback UI instead of the crashed subtree. Without one, an uncaught render error unmounts the entire React tree in React 16+. 🎯
There is still no Hook for this — you must use a class component (or the react-error-boundary library which wraps one).
The two methods#
class ErrorBoundary extends React.Component {
state = { hasError: false, error: null };
// Render phase: derive fallback state from the thrown error
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
// Commit phase: side effects — logging to Sentry etc.
componentDidCatch(error, info) {
logToService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
return <p role="alert">Something went wrong.</p>;
}
return this.props.children;
}
}
| Method | Phase | Purpose | Can set state? |
|---|---|---|---|
static getDerivedStateFromError |
render | Compute fallback UI | returns the new state |
componentDidCatch |
commit | Log / report side effects | this.setState allowed |
What it catches vs does NOT catch ⚠️#
| ✅ Catches | ❌ Does NOT catch |
|---|---|
| Errors in child render | Event handlers (use try/catch) |
| Child lifecycle methods | Async code (setTimeout, fetch, promises) |
| Child constructors | Server-side rendering |
| — | Errors thrown in the boundary itself |
Event handlers run outside render, so React can recover normally — wrap them in a plain try/catch and call setState to show an error yourself.
Using react-error-boundary#
The library gives a Hook-friendly API with reset support, avoiding hand-rolled classes:
import { ErrorBoundary } from "react-error-boundary";
function Fallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<p>{error.message}</p>
<button onClick={resetErrorBoundary}>Retry</button>
</div>
);
}
<ErrorBoundary
FallbackComponent={Fallback}
onReset={() => refetch()} // clear the failed state
resetKeys={[userId]} // auto-reset when a key changes
>
<Profile userId={userId} />
</ErrorBoundary>
🟢 Place boundaries at meaningful granularity — one per route/section — so a failing widget doesn't blank the whole page. Pair them with <Suspense> to handle both loading and error states.
flowchart TD
A["Child component renders"] --> B{"Throws during render/lifecycle?"}
B -->|"No"| C["Normal output"]
B -->|"Yes"| D["Nearest ErrorBoundary catches"]
D --> E["getDerivedStateFromError sets state"]
D --> F["componentDidCatch logs error"]
E --> G["Render fallback UI"]
Interview Q&A#
Q1. Why must an error boundary be a class component?
Only class lifecycle methods static getDerivedStateFromError and componentDidCatch expose the caught error. React provides no Hook equivalent, so even in modern codebases you write one class (or use react-error-boundary, which wraps one internally).
Q2. What does an error boundary NOT catch?
Errors in event handlers, asynchronous code (timeouts, promises, fetch callbacks), server-side rendering, and errors thrown in the boundary itself. These occur outside the child render/lifecycle path it monitors.
Q3. Difference between getDerivedStateFromError and componentDidCatch?
getDerivedStateFromError runs in the render phase and must be pure — it returns state to trigger the fallback. componentDidCatch runs in the commit phase and is for side effects like logging; it also receives the component stack.
Q4. How do you catch an error inside an onClick handler?
Error boundaries don't cover it. Wrap the handler body in try/catch and store the error in state yourself, or call a library helper like useErrorBoundary() from react-error-boundary to forward it to the nearest boundary.
Q5. How do you recover after a boundary trips?
Reset its state — with react-error-boundary call resetErrorBoundary() or change resetKeys. Hand-rolled boundaries reset by remounting the subtree (e.g. changing a key) or exposing a method that sets hasError back to false.