当前位置: 首页 > Web前端 > JavaScript

ErrorBoundaries就是这样实现的,还是蛮巧妙的

时间:2023-03-27 01:51:12 JavaScript

大家好,我是Kason。本文将讲解React中ErrorBoundaries的完整实现逻辑。一张图总结:这里简单介绍一下React的工作流程,后面会有用。分为三个步骤:触发updaterender阶段:计算updatecommit阶段带来的sideeffects阶段:在宿主环境执行sideeffectssideeffects有很多,比如:插入一个DOM节点,执行useEffectcallback好吧,下面进入正题。欢迎来到人类优质前端框架群,什么是ErrorBoundariesReact提供了两个错误处理相关的API:getDerivedStateFromError:静态方法,提供了错误发生时renderfallback的机会UIcomponentDidCatch:组件实例方法,当错误发生时出现的ClassComponents提供了使用这两个API记录错误消息的机会,通常称为错误边界。错误边界的后代组件中发生的React工作流中的所有错误都将被错误边界捕获。从一开始的介绍我们可以知道,React的工作流程是指:render阶段的commit阶段考虑了如下代码:);}render(){return

{this.props.children}
;}}constApp=()=>()A,B,C作为ErrorBoundary的后代组件,当错误发生在React工作流,会被ErrorBoundary中的componentDidCatch方法捕获。第1步:捕获错误首先查看工作流中的错误何时被捕获。render阶段的核心代码如下,出现的错误会由handleError处理:do{try{//对于并发更新,就是workLoopConcurrentworkLoopSync();休息;}catch(thrownValue){handleError(root,thrownValue);}}同时(真);commit阶段包括很多工作,比如:componentDidMount/Update执行绑定/解绑refuseEffect/useLayoutEffect回调和销毁执行。这些任务会以下面的形式执行,发生的错误会被captureCommitPhaseError处理:try{//...执行某项工作}catch(error){captureCommitPhaseError(fiber,fiber.return,error);}步骤2:构造回调发现即使没有ErrorBoundaries,工作流中的错误也已经被React捕捉到了。正确的逻辑应该是:如果有ErrorBoundaries,则执行相应的API,抛出React的提示信息;如果没有错误边界,抛出一个未捕获的错误。因此,无论是handleError还是captureCommitPhaseError,都会从发生错误的节点的父节点开始,逐层向上遍历,找到最近的ErrorBoundaries。一旦找到,将构造:用于执行ErrorBoundariesAPI的回调用于抛出React提示的回调//...为了可读性,逻辑已被删除functioncreateClassErrorUpdate(){if(typeofgetDerivedStateFromError==='function'){//执行getDerivedStateFromError的回调update.payload=()=>{returngetDerivedStateFromError(error);};//抛出React提示的回调update.callback=()=>{logCapturedError(fiber,错误信息);};}if(inst!==null&&typeofinst.componentDidCatch==='function'){//用于执行componentDidCatch的回调update.callback=functioncallback(){this.componentDidCatch(error);};}returnupdate;}如果没有找到ErrorBoundaries,继续向上遍历到根节点。这时候会构造:用于抛出未捕获错误的回调用于抛出React提示信息的回调//...为了可读性,删除了逻辑funffctioncreateRootErrorUpdate(){//用于抛出"notcallbackupdate.callback=()=>{onUncaughtError(error);logCapturedError(fiber,errorInfo);};returnupdate;}构造回调执行时执行回调呢子呢?在React中有两个API是执行user的-definedcallbacks:对于ClassComponent,this.setState(newState,callback)中的newState和callback参数都可以通过Function作为回调。因此,对于ErrorBoundaries,相当于主动触发更新:this.setState(()=>{//用于执行getDerivedStateFromError的回调},()=>{//用于执行componentDidCatch的回调//以及用于抛出React提示的回调})对于根节点,执行ReactDOM中的回调参数。渲染(元素,容器,callback)可以传递一个函数作为回调。因此,对于没有ErrorBoundaries的情况,相当于主动执行了如下函数:ReactDOM.render(element,container,()=>{//用于抛出“未捕获的错误”和“React提示信息"callback})因此,ErrorBoundaries的实现可以看作是:React利用了现有API实现的新功能。总结经常有人问:为什么Hooks没有ErrorBoundaries?可以看出,ErrorBoundaries的实现使用了this.setState来传递回调特性,useState暂时还不能完全对标。最后,留个作业给你。官方文档中有4种情况的错误不会被ErrorBoundaries捕获。运用这篇文章的知识,你能分析出为什么他们没有被抓到吗?