1. ErrorBoundary 的工作机制
- ErrorBoundary 是 React Router路由模块的一个特殊组件。
- 当某个路由的 loader、action、组件等发生错误时,React Router 会渲染"最近的"ErrorBoundary,而不是原本的页面组件。
- 这个机制不仅适用于 root 路由,也适用于任意嵌套路由。
2. 只在 root.tsx 定义可以吗?
- 可以:如果你只在 root.tsx 定义了 ErrorBoundary,那么所有未被更近一级 ErrorBoundary 捕获的错误,都会由 root.tsx 的 ErrorBoundary 兜底处理。
- 但不推荐只定义在 root:这样所有页面的错误都显示同一个兜底 UI,无法做到更细粒度的错误处理和更友好的用户体验。
3. 推荐做法 ------ 嵌套 ErrorBoundary
-
每个路由都可以有自己的 ErrorBoundary,这样只要该路由或其子路由出错,就能显示更贴合当前页面的错误信息。
-
例如:
/posts/:id
的 ErrorBoundary 可以显示"该文章不存在"/admin
的 ErrorBoundary 可以显示"管理后台出错,请联系管理员"
-
如果某个路由没有定义 ErrorBoundary,会自动向上查找父级路由的 ErrorBoundary,直到 root。
4. 典型代码结构
tsx
// root.tsx
export function ErrorBoundary({ error }) {
// 全局错误兜底
return <div>全局错误:{error.message}</div>;
}
// posts.tsx
export function ErrorBoundary({ error }) {
// 针对 posts 路由的错误处理
return <div>文章出错:{error.message}</div>;
}
- 这样
/posts/xxx
出错会显示 posts 路由的 ErrorBoundary,其他页面出错会显示 root 的 ErrorBoundary。
5. 适用场景
- 404 页面:在 loader 里 throw 404,可以让 posts 路由的 ErrorBoundary 显示"文章不存在"。
- 权限错误:在 admin 路由的 ErrorBoundary 里定制"无权限访问"提示。
- 全局异常:root.tsx 兜底所有未被捕获的错误。
6. 总结
- 只在 root.tsx 定义 ErrorBoundary 可以兜底,但不够灵活。
- 推荐在每个重要路由都定义 ErrorBoundary,实现更细致的错误处理和更好的用户体验。
- React Router 会自动选择"最近的"ErrorBoundary 渲染,无需手动分发错误。