Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
React 如何捕获组件树中的错误并渲染降级 UI。
错误边界是 React 类组件,它们捕获子组件树中任何地方的 JavaScript 错误,记录这些错误,并显示降级 UI 而不是使整个应用崩溃。它们的工作原理类似于 JavaScript 的 catch{'} 块,但用于组件树。错误边界捕获渲染期间、生命周期方法中和整个子树的构造函数中的错误。
当子树中的任何组件在渲染(或生命周期方法)中抛出时,React 开始通过 Fiber 树向上传播错误,寻找最近的错误边界。
React 向上遍历父 Fiber。如果找到实现了 getDerivedStateFromError 或 componentDidCatch 的类组件,它就在那里停止。如果到达根都没有找到,整个应用卸载。
React 在边界类上调用 getDerivedStateFromError(error)。这个静态方法返回新的 state(如 '{' hasError: true '}'),使边界重新渲染并显示降级 UI。
显示降级 UI 后,React 调用 componentDidCatch(error, errorInfo) — 这是向 Sentry 等日志服务发送错误的好地方。
边界组件检查其 state(hasError),渲染子组件(正常)或降级 JSX 元素。边界之外的应用其余部分继续正常工作。
静态类方法。在子组件抛出时在渲染阶段调用。返回新 state 以触发降级渲染。
实例方法。在降级渲染后的 commit 阶段调用。用于错误日志记录。接收 error + 组件堆栈。
错误通过 Fiber 树冒泡到最近的边界,就像异常通过调用栈冒泡一样。
边界可以通过更改其 key prop 来重置,这使 React 卸载并重新挂载整个子树。
1class ErrorBoundary extends React.Component {2 state = { hasError: false, error: null };34 static getDerivedStateFromError(error) {5 // Called during render — must be pure, no side effects6 return { hasError: true, error };7 }89 componentDidCatch(error, info) {10 // Called after commit — safe for side effects like logging11 logErrorToSentry(error, info.componentStack);12 }1314 render() {15 if (this.state.hasError) {16 return <FallbackUI error={this.state.error} />;17 }18 return this.props.children;19 }20}2122// Usage:23<ErrorBoundary>24 <MyComponent /> {/* If this throws, ErrorBoundary catches it */}25</ErrorBoundary>
没有错误边界,单个未处理的渲染错误会使整个 React 应用崩溃并显示空白屏幕。错误边界让你将失败隔离到 UI 的独立部分 — 应用的其余部分继续工作。这对于无法预测每种边缘情况的生产应用至关重要。
Your e-commerce app crashes in production when a product with malformed data renders. The entire page goes white and users see nothing — you lose the sale and have no visibility into what happened.
Without error boundaries, a single component throwing an error unmounts the ENTIRE React tree. The user sees a blank page. No error tracking fires because the crash happened during rendering, not in a try/catch block.
Wrap critical sections in error boundaries with strategic granularity: one around the product card, one around the cart, one around the whole page. Use componentDidCatch to send the error + componentStack to Sentry. Show a helpful fallback UI ('Something went wrong, refresh to try again') instead of a blank page.
Takeaway: Error boundaries are your PRODUCTION safety net. Place them at route level (catch everything), feature level (isolate failures), and widget level (for third-party components you don't control). Always log to an error tracking service in componentDidCatch.
You embed a third-party analytics chart widget in your dashboard. After a library update, the widget occasionally throws during rendering due to unexpected data formats.
The chart crash cascades — it's nested inside your dashboard layout, so the error propagates up and takes down the entire dashboard, including the navigation, sidebar, and all other widgets.
Wrap ONLY the third-party widget in its own error boundary. The fallback shows a placeholder ('Chart unavailable — refresh to retry'). The rest of the dashboard remains fully functional. Users can still use all other features while you investigate the chart issue.
Takeaway: Error boundaries give you component-level fault isolation, similar to microservice circuit breakers. Treat each third-party or unstable component as an isolated fault domain.