它是什么
包裹一段组件树,子树渲染抛错时显示 fallback,而不是整个应用白屏崩溃。
<ErrorBoundary fallback={<p>出错了,请刷新</p>}>
<MaybeBuggy />
</ErrorBoundary>
现状:必须是 Class 组件
到 React 19 仍然如此。函数 Error Boundary 还在路上——目前用 class 或现成库(如 react-error-boundary)。
自己写
class ErrorBoundary extends React.Component<
{ fallback: React.ReactNode; children: React.ReactNode },
{ hasError: boolean }
> {
state = { hasError: false };
static getDerivedStateFromError(error: Error) {
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
console.error('boundary caught:', error, info.componentStack);
// 上报 Sentry / 自家 logger
}
render() {
if (this.state.hasError) return this.props.fallback;
return this.props.children;
}
}
用 react-error-boundary 库(推荐)
npm i react-error-boundary
import { ErrorBoundary } from 'react-error-boundary';
function Fallback({ error, resetErrorBoundary }: any) {
return (
<div role="alert">
<p>出错:{error.message}</p>
<button onClick={resetErrorBoundary}>重试</button>
</div>
);
}
<ErrorBoundary
FallbackComponent={Fallback}
onError={(err, info) => reportToSentry(err, info)}
onReset={() => /* 清理状态 */ null}
>
<RealUI />
</ErrorBoundary>
它不捕获什么
- 事件回调里的错误:要自己
try/catch - 异步代码里的错误:自己
.catch() - SSR 报错:那是服务器端的事(Next.js 有
error.tsx) - Error Boundary 自己抛的错:要更外层一个 boundary 接住
function onClick() {
try {
doStuff();
} catch (e) {
console.error(e); // boundary 不接这种
}
}
在哪一层包
不是包整个应用一层就够——那样任何一处错误整页都崩。
经验:
<RootBoundary> // 兜底,整个应用一层
<Layout>
<RouteBoundary> // 每个路由一层(Next.js 自动有 error.tsx)
<Section>
<WidgetBoundary> // 高风险小部件单独一层(如第三方图表)
<ThirdPartyChart />
</WidgetBoundary>
</Section>
</RouteBoundary>
</Layout>
</RootBoundary>
Next.js 的内置错误处理
App Router 每个目录可以有 error.tsx:
// app/dashboard/error.tsx
'use client';
export default function Error({ error, reset }: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<h2>出错了</h2>
<button onClick={() => reset()}>重试</button>
</div>
);
}
它是个自动 Error Boundary,包裹该路由段。
全局错误(包括布局自身报错)用 app/global-error.tsx。
重置
错误 fallback 显示后,状态不会自动恢复——用户点重试需要把 boundary "reset"。
react-error-boundary 提供 resetErrorBoundary,并且当 resetKeys 数组里的值变了也会自动重置:
<ErrorBoundary FallbackComponent={Fallback} resetKeys={[userId]}>
<UserPanel userId={userId} />
</ErrorBoundary>
切换 userId → boundary 自动重置(之前用户的错误不影响新用户)。
配 Suspense 用
<ErrorBoundary FallbackComponent={ErrorView}>
<Suspense fallback={<Loading />}>
<RemoteData />
</Suspense>
</ErrorBoundary>
加载中走 Suspense;出错走 Error Boundary。这是 React 数据获取的现代范式。
→ 下一篇 受控 vs 非受控组件