React · Lesson 11 of 15
Suspense and Error Boundaries
Show fallbacks while data loads and recover when a subtree throws.
- Intermediate
- 16 min read
- 3 objectives
Before this lessonLesson 10: Transitions, Deferred Values and useId
What you will learn
- Wrap a tree in Suspense
- Write an error boundary
- Reset after a failure
Your Progress
0 of 15 lessons 0%
- Lessons0 / 15
- Completed0
- Est. time left~ 4 hours
Create a free account to keep your progress on every device.
Two wrappers keep a crashed or loading subtree from taking down the page: Suspense for waiting, and an error boundary for thrown errors.
Suspense
A child that suspends (a data library using a Promise, or a lazy component) bubbles up to the nearest Suspense, which shows its fallback.
import { Suspense, lazy } from "react";
const Chart = lazy(() => import("./Chart"));
function Dashboard() {
return (
<Suspense fallback={<p>Loading chart…</p>}>
<Chart />
</Suspense>
);
}You can nest Suspense to stream parts of the page independently. Pair it with a data library that supports it (React Query, Relay, Next.js) rather than throwing Promises by hand.
Error boundaries
A class component with getDerivedStateFromError catches render errors in its children. Function components cannot do this yet.
import { Component } from "react";
class ErrorBoundary extends Component {
state = { error: null };
static getDerivedStateFromError(error) {
return { error };
}
render() {
if (this.state.error) {
return (
<p role="alert">
Something broke.{" "}
<button onClick={() => this.setState({ error: null })}>Retry</button>
</p>
);
}
return this.props.children;
}
}Boundaries catch errors in render, lifecycle and constructors of children. They do not catch errors in event handlers or async code: use try/catch there.
