我的编程空间,编程开发者的网络收藏夹
学习永远不晚

React工作流程及ErrorBoundaries实现过程讲解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

React工作流程及ErrorBoundaries实现过程讲解

这里简单讲解下React工作流程,后文有用。分为三步:

触发更新

  • render阶段:计算更新会造成的副作用
  • commit阶段:在宿主环境执行副作用

副作用有很多,比如:

  • 插入DOM节点
  • 执行useEffect回调

好了,让我们进入主题。

什么是Error Boundaries

React提供了两个与错误处理相关的API:

  • getDerivedStateFromError:静态方法,当错误发生后提供一个机会渲染fallback
  • UIcomponentDidCatch:组件实例方法,当错误发生后提供一个机会记录错误信息

使用了这两个API的ClassComponent通常被称为Error Boundaries(错误边界)。

在Error Boundaries的子孙组件中发生的所有React工作流程内的错误都会被Error Boundaries捕获。

通过开篇的介绍可以知道,React工作流程指:

render阶段

commit阶段

考虑如下代码:

class ErrorBoundary extends Component {
  componentDidCatch(e) {
    console.warn(“发生错误”, e);
  }
  render() {
    return <div>{this.props.children}</div>;
  }
}
const App = () => (
    <ErrorBoundary>
    <A><B/></A>
    <C/>
    <ErrorBoundary>
)

A、B、C作为ErrorBoundary的子孙组件,当发生React工作流程内的错误,都会被ErrorBoundary中的componentDidCatch方法捕获。

步骤1:捕获错误

首先来看工作流程中的错误都是何时被捕获的。

render阶段的核心代码如下,发生的错误会被handleError处理:

do {
  try {
    // 对于并发更新则是workLoopConcurrent
workLoopSync();
    break;
  } catch (thrownValue) {
    handleError(root, thrownValue);
  }
} while (true);

commit阶段包含很多工作,比如:

  • componentDidMount/Update执行
  • 绑定/解绑ref
  • useEffect/useLayoutEffect callback与destroy执行

这些工作会以如下形式执行,发生的错误被captureCommitPhaseError处理:

try {
// …执行某项工作 
} catch (error) {
  captureCommitPhaseError(fiber, fiber.return, error);
}

步骤2:构造callback

可以发现,即使没有Error Boundaries,工作流程中的错误已经被React捕获了。而正确的逻辑应该是:

  • 如果存在Error Boundaries,执行对应API
  • 抛出React的提示信息
  • 如果不存在Error Boundaries,抛出未捕获的错误

所以,不管是handleError还是captureCommitPhaseError,都会从发生错误的节点的父节点开始,逐层向上遍历,寻找最近的Error Boundaries。

一旦找到,就会构造:

  • 用于执行Error Boundaries API的callback
  • 用于抛出React提示信息的callback
  // ...为了可读性,逻辑有删减
function createClassErrorUpdate() {
  if (typeof getDerivedStateFromError === 'function') {
// 用于执行getDerivedStateFromError的callback
    update.payload = () => {
      return getDerivedStateFromError(error);
};
// 用于抛出React提示信息的callback
    update.callback = () => {
      logCapturedError(fiber, errorInfo);
    };
  }
  if (inst !== null && typeof inst.componentDidCatch === 'function') {
// 用于执行componentDidCatch的callback
    update.callback = function callback() {
      this.componentDidCatch(error);
    };
  }
  return update;
}

如果没有找到Error Boundaries,继续向上遍历直到根节点。

此时会构造:

用于抛出未捕获错误的callback用于抛出React提示信息的callback

// ...为了可读性,逻辑有删减
funffction createRootErrorUpdate() {
  // 用于抛出“未捕获的错误”及“React的提示信息”的callback
  update.callback = () => {
    onUncaughtError(error);
    logCapturedError(fiber, errorInfo);
  };
  return update;
}

执行callback

构造好的callback在什么时候执行呢?

在React中有两个执行用户自定义callback的API:

对于ClassComponent, this.setState(newState, callback)中newState和callback参数都能传递Function作为callback

所以,对于Error Boundaries,相当于主动触发了一次更新:

this.setState(() => {
  // 用于执行getDerivedStateFromError的callback
}, () => {
  // 用于执行componentDidCatch的callback
  //  以及 用于抛出React提示信息的callback
})

对于根节点,执行ReactDOM.render(element, container, callback)中callback参数能传递Function作为callback

所以,对于没有Error Boundaries的情况,相当于主动执行了如下函数:

ReactDOM.render(element, container, () => {
// 用于抛出“未捕获的错误”及“React的提示信息”的callback
})

所以,Error Boundaries的实现可以看作是:React利用已有API实现的新功能。

总结

经常有人问:为什么Hooks没有Error Boundaries?

可以看到,Error Boundaries的实现借助了this.setState可以传递callback的特性,useState暂时无法完全对标。

以上就是React工作流程及Error Boundaries实现过程讲解的详细内容,更多关于React工作流程Error Boundaries实现过程的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

React工作流程及ErrorBoundaries实现过程讲解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

一文讲解Git的工作流程

Git是一个流行的分布式版本控制系统,它可以帮助团队协作开发代码。在使用Git时,开发人员需要了解工作流程,以便能够更好地协作工作。接下来,本文将讲解Git的工作流程。一、Git的基本概念在深入讨论Git的工作流程之前,我们先了解一些Git
2023-10-22

GoLang实现日志收集器流程讲解

这篇文章主要介绍了GoLang实现日志收集器流程,看日志是开发者平时排查BUG所必须的掌握的技能,但是日志冗杂,所以写个小工具来收集这些日志帮助我们排查BUG,感兴趣想要详细了解可以参考下文
2023-05-20

Yii使用queue实现队列流程讲解

Yii是一个高性能的PHP5的web应用程序开发框架。通过一个简单的命令行工具yiic可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发
2022-11-13

C++map与set封装实现过程讲解

setset是一种关联式容器,下面这篇文章主要给大家介绍了关于C++中map和set使用的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友可以参考下
2023-03-08

Flink自定义Sink端实现过程讲解

这篇文章主要介绍了Flink自定义Sink端实现过程,在Fink官网中sink端只是给出了常规的writeapi.在我们实际开发场景中需要将flink处理的数据写入kafka,hbasekudu等外部系统
2023-01-28

SpringBoot整合JPA框架实现过程讲解

在开发中,我们通常会对数据库的数据进行操作,Sprirng Boot对关系型数据库和非关系型数据库的访问操作都提供了非常好的整合支持
2022-12-21

java 工作流引擎设计实现解析流程定义文件

这篇文章主要为大家介绍了java 工作流引擎设计与实现及流程定义文件解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-19

vue+jsplumb实现工作流程图的方法

这篇文章主要介绍“vue+jsplumb实现工作流程图的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue+jsplumb实现工作流程图的方法”文章能帮助大家解决问题。先写了一个demo,大概
2023-06-30

GitLab的多仓库协同工作流程及实践

GitLab的多仓库协同工作流程及实践【引言】在软件开发过程中,特别是在大型项目中,通常需要同时维护多个代码仓库。GitLab作为一个强大的代码托管平台,提供了各种功能来支持多仓库的协同工作。本文将介绍GitLab的多仓库协同工作流程及实践
2023-10-22

React路由动画切换实现过程详解

这篇文章主要介绍了react-router路由切换动画的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
2022-12-08

SQL实现数据过滤流程详解

目录数据准备student 表过滤数据过滤单个值过滤null 值过滤集合BETWEEN IN NOT IN使用通配符过滤数据LIKE使用逻辑操作符组合WHERE子句数据准备student 表CREATE TABLE `student` (
2023-01-05

Spring Security PasswordEncoder密码加密实现过程讲解

这篇文章主要介绍了SpringSecurityPasswordEncoder密码加密匹配操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2023-01-03

微信小程序自定义tabbar栏实现过程讲解

tabBar相对而言用的还是比较多的,但是用起来并没有难,下面这篇文章主要给大家介绍了关于微信小程序全局配置之tabBar的相关资料,文中通过图文以及示例代码介绍的非常详细,需要的朋友可以参考下
2023-02-01

Golang分布式注册中心实现流程讲解

这篇文章主要介绍了Golang分布式注册中心实现流程,注册中心可以用于服务发现,服务注册,配置管理等方面,在分布式系统中,服务的发现和注册是非常重要的组成部分,需要的朋友可以参考下
2023-05-19

编程热搜

目录