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
| Place | What it protects |
|---|---|
Around the whole App | At least a message instead of a blank screen |
| Around each page in the layout | An error on a page does not break the menu |
| Around an independent block | The 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.