Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Error boundaries

If a component throws an exception while rendering, React removes the whole app from the page — the user sees a blank screen. An error boundary is a wrapper component that catches such errors in its children and shows a fallback UI instead. The rest of the page keeps working.

What breaks the page

Suppose a blog post arrived without a title and the component does not expect that:

// src/components/PostCard.jsx
export default function PostCard({ post }) {
  return <h2>{post.title.toUpperCase()}</h2>;
}

If post.title is undefined, calling toUpperCase() throws a TypeError. Without an error boundary the whole page goes white, and the error shows only in the console.

The boundary component

An error boundary can only be written as a class — there is no hook for it. Create src/components/ErrorBoundary.jsx once and use it across the project:

// src/components/ErrorBoundary.jsx
import { Component } from 'react';
 
export default class ErrorBoundary extends Component {
  state = { hasError: false };
 
  static getDerivedStateFromError() {
    return { hasError: true };
  }
 
  componentDidCatch(error, info) {
    console.error('Error in a component:', error, info.componentStack);
  }
 
  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}

getDerivedStateFromError is called on an error in any descendant and switches the state. componentDidCatch is the place to log the error or send it to a monitoring service. While there is no error, the boundary simply renders children.

Using it

Wrap the risky part of the page and pass the fallback markup in the fallback prop:

// src/pages/HomePage.jsx
import ErrorBoundary from '../components/ErrorBoundary.jsx';
import PostList from '../components/PostList.jsx';
 
export default function HomePage() {
  return (
    <>
      <h1>Blog</h1>
      <ErrorBoundary fallback={<p>Could not show the posts.</p>}>
        <PostList />
      </ErrorBoundary>
    </>
  );
}

If an error happens in PostList or any card inside it, "Could not show the posts." appears instead of the list, while the "Blog" heading and the menu stay in place.

Where to put boundaries

PlaceWhat it protects
Around the whole AppAt least a message instead of a blank screen
Around each page in the layoutAn error on a page does not break the menu
Around an independent blockThe comments failed, the post is still there

A ready-made library

To avoid writing a class, you can install the react-error-boundary package (npm install react-error-boundary). Its ErrorBoundary component takes the same fallback prop and can reset the error with a "Try again" button.

Common mistake

A boundary catches only errors during rendering and in effects. It does not see errors in event handlers or asynchronous code:

// The boundary does NOT catch this error: it is in a click handler.
<button onClick={() => { throw new Error('Failure'); }}>Delete</button>

Handle such errors yourself with try/catch and show a message through state, as in the data loading lesson.

Thanks for reading!

Donate to the site — we work hard for you.