You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
getSnapshotBeforeUpdate, componentDidCatch and getDerivedStateFromError: There are no Hook equivalents for these methods yet, but they will be added soon.
前言
React
项目中,很常见遇到页面由于某个React
组件渲染错误(代码书写错误不规范或后端接口字段调整出错),导致整个应用被挂载出现白屏,且可能无法追踪造成影响极大,究其原因觉得是React
设计的坑点 自 React 16 起,任何未被错误边界捕获的错误将会导致整个 React 组件树被卸载。 针对此类问题,我们如何来进行感知上报以及应急兜底呢🤔️?Error Boundaries
是 React16 提出来用来捕获渲染时错误的概念,Error Boundaries
是一种 React 组件,这种组件可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,且会渲染出兜底 UI。Error Boundaries
Error Boundaries
可以用来捕获渲染时错误,API 如下:static getDerivedStateFromError
:在出错后有机会修改state
触发最后一次错误fallback
的渲染。componentDidCatch
:用于出错时副作用代码,比如错误上报等。这两种方法中任意一个被定义时,这个组件就会成为
Error Boundaries
组件,可以阻止子组件渲染时报错。错误边界的工作方式类似于
JavaScript
的catch {}
,不同的地方在于错误边界只针对React
组件。只有class
组件才可以成为错误边界组件。建议将
Error Boundary
单独作为一个组件,而不是将错误监听方法与业务组件耦合,一方面考虑到复用,另一方面则因错误检测只对子组件生效。注意
: 错误边界仅可以捕获其子组件的错误,无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,这也类似于JavaScript
中catch {}
的工作机制。Error Boundaries 无法捕获错误
React Error Boundaries 官方文档 里提到了四种无法 Catch 的错误场景:
回调事件,由于回调事件执行时机不在渲染周期内,因此无法被
Error Boundaries Catch
住,如有必要得自行try/catch
异步代码,比如
setTimeout
或requestAnimationFrame
,和第一条同理服务端渲染
Error Boundaries
组件自身触发的错误,只能捕获其子组件的错误这也是使用
Error Boundaries
最容易有疑问的地方。对于不能捕获到的错误情况, 是因为
getDerivedStateFromError
执行在render
阶段,componentDidCatch
执行在commit
阶段,过了这两个阶段(即一次渲染周期)就无法捕获到。Error Boundaries 可作用于 Function Component
虽然函数式组件无法定义
Error Boundaries
,但Error Boundaries
可以捕获函数式组件的异常错误:注意
:出现在deps
中的错误会立即被Catch
,导致console.log(1)
都无法打印。但如果是下面的代码,则可以打印出console.log(1)
,无法打印出console.log(2)
:所以
React
官网的这句话并不是指Error Boundaries
对Hooks
不生效,而是指Error Boundaries
无法以Hooks
方式指定,对功能是没有影响的:总结
Error Boundaries
可以捕获所有子元素渲染时异常,包括render
、各生命周期函数,但也有很多使用限制,我们需要正确使用它。Error Boundaries
也不是万能的,更多时候我们要避免并及时修复错误以及错误兜底降低影响,并在第一时间内监控起来并快速修复。Other Resources
Error Boundaries
static-getderivedstatefromerror
componentdidcatch
use-error-boundary
React Lifecycle Methods diagram
The text was updated successfully, but these errors were encountered: