Skip to content

React Error Boundaries: Stop the White Screen of Death

Posted on:January 13, 2026 at 10:00 AM

Hey there! đź‘‹

Have you ever been browsing a website, clicked a button, and suddenly… poof? The entire screen goes white. No error message, no “Oops”, just a blank void of nothingness.

If you’re a developer, you know this is the dreaded White Screen of Death. It happens when a JavaScript error crashes the entire React component tree.

But guess what? We can fix that. Today, I’m going to show you how to use React Error Boundaries to handle these crashes gracefully. Think of it as a safety net for your app.

What is an Error Boundary?

In simple terms, an Error Boundary is a React component that catches JavaScript errors anywhere in its child component tree.

Instead of crashing the whole app, it displays a fallback UI (like “Something went wrong”) while the rest of the app keeps working.

Important Note: As of React 18, Error Boundaries must be Class Components. You can’t write them as Functional Components with Hooks yet. A bit old school, I know, but it works perfectly.

Creating the Error Boundary

Let’s write some code. We’ll create a class component called ErrorBoundary.

import React from "react";

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    // State to track if an error has occurred
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service like Sentry
    console.error("Uncaught error:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return (
        <div className="p-4 bg-red-100 text-red-700 border border-red-400 rounded">
          <h2>Oops! Something went wrong.</h2>
          <p>Don't worry, our team has been notified.</p>
        </div>
      );
    }

    // If no error, render the children components as usual
    return this.props.children;
  }
}

export default ErrorBoundary;

Here is what’s happening:

  1. getDerivedStateFromError: This lifecycle method runs when an error occurs. We use it to update the state (hasError: true).
  2. componentDidCatch: This is where we can log the error. In a real app, you’d send this to a monitoring service.
  3. render: If hasError is true, we show a friendly message. Otherwise, we show the content (this.props.children).

How to Use It

Now that we have our safety net, we just need to wrap our risky components with it.

You can wrap the entire app:

import ErrorBoundary from "./ErrorBoundary";
import App from "./App";

// In your index.js or main entry file
<ErrorBoundary>
  <App />
</ErrorBoundary>

Or, even better, wrap specific parts of your UI. If a widget crashes, the rest of the page stays alive!

import ErrorBoundary from "./ErrorBoundary";
import UserProfile from "./UserProfile";
import UserFeed from "./UserFeed";

const Dashboard = () => {
  return (
    <div>
      <h1>My Dashboard</h1>

      {/* If UserProfile crashes, UserFeed still works! */}
      <ErrorBoundary>
        <UserProfile />
      </ErrorBoundary>

      <ErrorBoundary>
        <UserFeed />
      </ErrorBoundary>
    </div>
  );
};

Limitations

Error Boundaries are powerful, but they don’t catch everything. They won’t catch errors in:

For event handlers, you should stick to the classic try...catch block.

Wrapping Up

No one writes perfect code. Bugs happen. But with Error Boundaries, you ensure that a single bug doesn’t take down your entire application.

It improves the user experience significantly. Instead of a confusing white screen, users get a helpful message, and you get a chance to recover.

Give it a try in your next project. Your users (and your peace of mind) will thank you! 🛡️