外观
React 里错误怎么接住?
渲染期间、生命周期里和构造函数里的错误,用错误边界接住,避免一整棵树卸掉。事件处理、异步代码和 SSR 里的错误,边界接不住,要自己 try/catch 或在 Promise 上处理。
原理
错误边界是类组件,实现 getDerivedStateFromError 或 componentDidCatch。前者用来渲染备用 UI,后者用来打日志。备用 UI 放在边界里面,边界本身不能在 render 里再抛一次。
jsx
class Boundary extends React.Component {
state = { error: null }
static getDerivedStateFromError(error) {
return { error }
}
render() {
if (this.state.error) return <p>这块暂时不可用</p>
return this.props.children
}
}路由级放一个边界,重的第三方组件再单独包一层。这样一块图表挂了,导航还在。
事件里的异常发生在 React 的渲染调用之外,用事件回调里的 try/catch。请求失败进状态,不要抛进渲染。window 上的 error 和 unhandledrejection 用来兜底上报,不能代替边界去渲染备用界面。
追问
函数组件能当边界吗?
不能只靠 Hook 实现 componentDidCatch 的语义。可以写一个类边界,函数组件放在它里面。有的库用 Hook 风格的 API 包了类边界。
开发环境和生产环境的表现?
开发环境会覆盖一层错误提示,方便看栈。生产环境才是用户看到的备用 UI。两套都要看边界有没有包对位置。
易错点
- 边界放得太靠上,任何错误都变成整页故障。
- 在事件里抛错,以为边界会渲染备用 UI。
- 备用 UI 再次抛错,错误冒到更外层,甚至空白页。