react进阶教程之异常处理机制error Boundaries

 更新时间:2022年08月08日 11:57:04   作者:陈铭-机器学习  
在react中一旦出错,如果每个组件去处理出错情况则比较麻烦,下面这篇文章主要给大家介绍了关于react进阶教程之异常处理机制error Boundaries的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

该文章翻译自官网 https://reactjs.org/docs/error-boundaries.html 该文章包含以下内容:

1.Error Boundaries介绍

2.ComponentDidCatch 函数的参数

3.触发error boundaries后程序要走向哪里?

4.对于不能捕获的错误的新处理方式

5.在堆中跟踪component

6.try/catch 如何?

7.Event Handlers怎么样?

8.React 15后的函数命名改变

在过去,React组件中的js错误通常会污染React的内部state并且造成它发出一个让人难以理解的错误给下一个Render,我们在控制台看到的异常往往是由更内层的程序代码引起的,但是React并没有提供一个方式让我们在组件中优雅的解决他们并恢复业务逻辑。

Error Boundaries介绍

UI的某部分引起的JS错误不应该破坏整个程序,为了帮React的使用者解决这个问题,React 16介绍了一种关于错误边界(error boundary)的新观念。

error boundaries 让react组件可以捕获在他们子级组件树任何地方的错误,并且打印出这些错误和演示一个预备UI(fallback UI),从而替换那些出现异常的组件树。Error boundaries在rendering,lifeCyclemethod或处于他们树层级之下的构造函数中捕获错误。

(注释:lifecycle method是react固有名词,包括componentWillUpdate,componentWillReceiveProps,render等方法,这些方法会自动调用)

注意: error boundaries并不会捕捉这些错误:

1.事件处理器

2.异步代码

3.服务端的渲染代码

4.在error boundaries区域内的错误

在这个lifecycle method: componentDIdCatch(error,info) 里的类会变成一个 error boundary

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
 
  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }
 
  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

然后你就可以像一个普通组件一样使用它

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

componentDidCatch()方法像JS的catch{}模块一样工作,但是对于组件,只有class类型的组件(class component)可以成为一个error boundaries,在实际上,大多数情况下你可能只需要在整个程序中定义一个error boundary组件,然后你就可以一直使用它了!

请注意error boundaries仅仅可以捕获到在他们树的层级下面的错误,而不能捕获到本层级的错误,如果一个error boundaries渲染错误信息失败了,那么这个错误将会传播到一个在它层级上面,并且离它最近的error boundary 。这就像js的{}模块的工作机制一样。

ComponentDidCatch 参数

  • error: 这是一个已经被抛出的错误
  • info:这是一个componentStack key。这个属性有关于抛出错误的组件堆的信息
componentDidCatch(error, info) {
  
  /* Example stack information:
     in ComponentThatThrows (created by App)
     in ErrorBoundary (created by App)
     in div (created by App)
     in App
  */
  logComponentStackToMyService(info.componentStack);

触发error boundaries后程序要走向哪里?

关于error boundaries的后续处理由你做主,你可能会指定一个最高等级的路由组件去给用户标识某些地方出了问题,就像服务端的框架处理异常一样,你也可以指定一个在错误边界内的个人的小页面让整个程序不至于发生崩溃。

对于不能捕获的错误的新处理方式

这种变化有一个重要的新含义,对于React 16,没有被任何error boundary捕获的错误将会导致整个React组件树的崩溃。

我们对这个决定有争论,但是在我们的经验里,留下一个崩溃的UI界面比完全移除它要糟糕,例如,在一个产品比如聊天器中,留下一个崩坏的UI界面可能会导致某个人发送信息给一个并非他想要发送的人。同样的,对于一个支付类的app来说,不要显示任何东西显然比显示一个错误的金额数目要好。

这个改动意味着如果你迁移到React 16,你可能会发现一些以前没有注意到的,并且是确确实实存在的在你程序中的异常,增加error boundaries会让你在某些地方出现问题的时候可以提供更好的用户体验。

举个例子,facebook的侧边栏,信息面板,对话记录以及消息输入框处于被分割开来的error boundaries中,如果在他们的UI子组件中发生了崩溃事件,那么其他的组件还可以正常运行。

我们同样鼓励你使用JS 错误报道服务(或者你自己建立一个),然后你就可以了解到这些未被处理的异常是如何发生的,接着解决他们。

在堆中跟踪component

React 16 会把所有render过程中发生的错误打印给开发者,即使程序意外的包含了它。它不仅仅提供了错误信息和追踪js堆,也提供了组件的堆路径,现在你可以精确的看到组件树中错误发生的地方。

Error caught by Error Boundary component

你同样可以在组件的堆追踪中看到文件名字和行数,这是creat react app项目的默认配置

Error caught by Error Boundary component with line numbers

如果你没有使用Create React App ,你也可以通过添加这个插件,手动的管理你的babel配置。注意:它必须严格的限制在开发过程中使用,生产过程一定要剔除。

注意: 在堆的追踪中看到的组件名字取决于 Function.name属性。如果你想要支持那些现在还没有原生提供这些的浏览器和设备,比如ie11,consider including a Function.name polyfill in your bundled application, such as function.name-polyfill. 否则,你必须明确的在你所有的组件中都设置displayName.

try/catch 如何?

try/catch是非常棒的但是它只在imperative code(命令式代码)中起作用

try {
  showButton();
} catch (error) {
  // ...
}

然而,react组件是声明式的并且指定应该被渲染的内容

<Button />

Error boundaries保留了React的声明式性质,并且拥有你期待的表现。比如,即使通过某个在树的深层setState,在componentDidUpdate拦截中发生了错误,它也仍然会被正确的传送到最近的error boundary。

Event Handlers怎么样?

error boundaries并不能捕获event handles中的异常。

React并不需要error boundaries从event handles中恢复错误。与render方法和lifecycle拦截不同的是,event Handles并不会在rendering期间发生。所以如果他们被抛出,React仍然知道怎么去渲染。

如果你需要捕获event handler,使用普通的js代码try/catch 声明

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }
  
  handleClick = () => {
    try {
      // Do something that could throw
    } catch (error) {
      this.setState({ error });
    }
  }
 
  render() {
    if (this.state.error) {
      return <h1>Caught an error.</h1>
    }
    return <div onClick={this.handleClick}>Click Me</div>
  }
}

注意以上代码仅仅展示通常的js习惯,而没有使用error boundaries。

React 15后的函数命名改变

React 15通过unstable_handleError方法 包含了一些有限的error boundaries支持。这个方法现在已经不能运用,你需要使用compoentDIdCatch。

总结

到此这篇关于react进阶教程之异常处理机制error Boundaries的文章就介绍到这了,更多相关react异常处理机制error Boundaries内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React项目中hook实现展示对话框功能

    React项目中hook实现展示对话框功能

    Modal(模态框)是 web 开发中十分常见的组件,即从页面中弹出的对话框,下面这篇文章主要给大家介绍了关于React项目中hook实现展示对话框功能的相关资料,需要的朋友可以参考下
    2022-05-05
  • react-diagram 序列化Json解读案例分析

    react-diagram 序列化Json解读案例分析

    今天带来大家学习react-diagram 序列化Json解读的相关知识,本文通过多种案例给大家分析序列化知识,通过图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2021-05-05
  • React中实现插槽效果的方案详解

    React中实现插槽效果的方案详解

    在React中是没有插槽的概念的, 或者说在React中是不需要插槽的, 因为React对于这种需要插槽的情况非常灵活,本文给大家分享两种方案实现,分别是children实现插槽和props实现插槽,结合实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2022-09-09
  • 原生实现一个react-redux的代码示例

    原生实现一个react-redux的代码示例

    这篇文章主要介绍了原生实现一个react-redux的代码示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • react.js 获取真实的DOM节点实例(必看)

    react.js 获取真实的DOM节点实例(必看)

    下面小编就为大家带来一篇react.js 获取真实的DOM节点实例(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • React图片压缩上传统一处理方式

    React图片压缩上传统一处理方式

    这篇文章主要介绍了React图片压缩上传统一处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 关于React Native 无法链接模拟器的问题

    关于React Native 无法链接模拟器的问题

    许多朋友遇到React Native 无法链接模拟器的问题,怎么解决呢,本文给大家分享完整简便解决方法及配置例题,对React Native 链接模拟器相关知识感兴趣的朋友一起看看吧
    2021-06-06
  • Vite + React从零开始搭建一个开源组件库

    Vite + React从零开始搭建一个开源组件库

    这篇文章主要介绍了Vite + React 如何从0到1搭建一个开源组件库,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • React大屏可视化脚手架教程示例

    React大屏可视化脚手架教程示例

    这篇文章主要为大家介绍了React大屏可视化脚手架教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 基于React Hooks的小型状态管理详解

    基于React Hooks的小型状态管理详解

    本文主要介绍一种基于 React Hooks 的状态共享方案,介绍其实现,并总结一下使用感受,目的是在状态管理方面提供多一种选择方式。感兴趣的小伙伴可以了解一下
    2021-12-12

最新评论