什么是错误边界,有什么用
What are error boundaries and How are they useful
一句话:一个能捕获子树渲染错误的类组件, 出错时渲染兜底 UI,而不是让整个应用白屏。
怎么写:实现 getDerivedStateFromError(用来切换到兜底 UI)和componentDidCatch(用来上报日志)。目前必须是 class 组件—— 没有对应的 hook。
抓不到什么(这才是考点):
- 事件处理函数里的错误—— 因为那不在渲染过程中。 要自己
try/catch。 - 异步代码里的错误——
setTimeout、 Promise 回调(和 #310 同一个道理)。 - 服务端渲染。
- 错误边界自己抛的错。
放哪:粒度要合适。只在根节点放一个, 一个小组件挂了整页还是没了;推荐按「独立区块」放—— 每个路由页面、 每个可独立失败的挂件 (侧栏、图表、评论区)。 这样一块坏了其他还能用。
会追问:「怎么让用户能恢复?」—— 兜底 UI 里给一个「重试」按钮, 把边界的 state 重置 (或者换一个 key强制重建子树)。react-error-boundary这个库提供了 resetErrorBoundary。
In one line: a class component that catches render errors in its subtree and renders a fallback UI instead of letting the whole app go blank.
How you write one: implement getDerivedStateFromError (to switch to the fallback) and componentDidCatch (to report the error). It still has to be a class component — there is no hook equivalent.
What it does not catch — this is the real question:
- Errors inside event handlers — those do not happen during render. Use your own
try/catch. - Errors in async code —
setTimeout, Promise callbacks (the same reason as #310). - Server-side rendering.
- Errors thrown by the boundary itself.
Where to put them: get the granularity right. One at the root only means a single broken widget still wipes out the page; put one around each independent block — each route, and each widget that can fail on its own (sidebar, chart, comments). Then one broken block leaves the rest usable.
Follow-up: “How does the user recover?” — give the fallback a “Retry” button that resets the boundary’s state (or changes a key to force the subtree to rebuild). The react-error-boundary library gives you resetErrorBoundary for this.