Skip to main content

Error in a component

Short version: any unhandled error during a component's render/commit "tears apart" the entire React subtree from the nearest Error Boundary up to the root. If there is no boundary, the entire root React node crashes → a blank screen.


What exactly happens

  • During the render phase, React calls your components (functions/constructors) and builds the virtual tree. If a throw happens inside (or an error like cannot read property of undefined), React interrupts reconciliation.
  • Next comes the commit phase (applying changes to the DOM). An error in layout effects (useLayoutEffect) or in a class's lifecycle can also cause the subtree to unmount abruptly.
  • If there is no Error Boundary nearby, React doesn't know how to safely continue → it unmounts the entire application tree (or the corresponding sub-root). Hence: "one component crashed, the whole screen disappeared".

Error Boundary: a fuse

An Error Boundary catches errors in child components during:

  • render
  • class component constructors
  • lifecycle methods and shows a fallback UI instead of crashing the whole application.

A minimal example

javascript
class ErrorBoundary extends React.Component< { fallback?: React.ReactNode }, { hasError: boolean } > { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error: any, info: any) { // log to Sentry/GlitchTip, etc. } render() { return this.state.hasError ? (this.props.fallback ?? <h1>Something went wrong</h1>) : this.props.children; } }

Wrap risky areas:

javascript
<ErrorBoundary fallback={<Oops />}> <RiskyWidget /> </ErrorBoundary>

For functions, it's convenient to use the ready-made react-error-boundary package.


What an Error Boundary does not catch

  • Errors in event handlers (use try/catch there).
  • Errors in asynchronous code (timers, fetch, promises, await); catch these manually (try/catch, .catch, window.onunhandledrejection).
  • Errors on the server during SSR.
  • Errors inside the Error Boundary itself (obviously).

Typical causes of "crashes"

  • Accessing undefined/null during render (no data checks).
  • Infinite render loops (changing state in render/a dependency-less useEffect).
  • Unpredictable effects in useLayoutEffect/useEffect that throw.
  • Hydration (SSR) with a critical markup mismatch.
  • Throwing exceptions as part of the logic (for example, combined with Suspense) without a proper boundary.

Practices so the app doesn't "crash entirely"

  1. Segment the app with several Error Boundaries: header, sidebar, content, modals, so a widget crash doesn't take everything down.
  2. Smart fallbacks: "Try again", "Report the error", telemetry.
  3. Protect the render: data checks (if (!data) return <Skeleton/>), optional chaining, types (TypeScript).
  4. Asynchrony: try/catch around await, a centralized .catch, onerror/unhandledrejection handlers.
  5. Monitoring: hook up Sentry/GlitchTip to catch stack traces, frequencies, affected users.
  6. Feature flags/kill switches: quickly disable problematic features.
  7. Tests and Strict Mode: React's dev mode calls some paths twice, which helps surface errors earlier.

Summary

An error in a component "breaks everything" because, without the nearest Error Boundary, React is forced to unmount the entire tree up to the root to preserve UI integrity. The solution is to localize the risk with Error Boundaries, careful asynchronous handling, and defensive checks at render time.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.