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

目录
  • Error Boundaries介绍
  • ComponentDidCatch 参数
    • 触发error boundaries后程序要走向哪里?
  • 对于不能捕获的错误的新处理方式
  • 在堆中跟踪component
  • try/catch 如何?
  • Event Handlers怎么样?
  • React 15后的函数命名改变
  • 总结

该文章翻译自官网 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堆,也提供了组件的堆路径,现在你可以精确的看到组件树中错误发生的地方。

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

如果你没有使用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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解React 16 中的异常处理

    详解React 16 中的异常处理 异常处理 在 React 15.x 及之前的版本中,组件内的异常有可能会影响到 React 的内部状态,进而导致下一轮渲染时出现未知错误.这些组件内的异常往往也是由应用代码本身抛出,在之前版本的 React 更多的是交托给了开发者处理,而没有提供较好地组件内优雅处理这些异常的方式.在 React 16.x 版本中,引入了所谓 Error Boundary 的概念,从而保证了发生在 UI 层的错误不会连锁导致整个应用程序崩溃:未被任何异常边界捕获的异常可能会导致

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

    目录 Error Boundaries介绍 ComponentDidCatch 参数 触发error boundaries后程序要走向哪里? 对于不能捕获的错误的新处理方式 在堆中跟踪component try/catch 如何? Event Handlers怎么样? React 15后的函数命名改变 总结 该文章翻译自官网 https://reactjs.org/docs/error-boundaries.html 该文章包含以下内容: 1.Error Boundaries介绍 2.Compo

  • Java进阶教程之异常处理

    程序很难做到完美,不免有各种各样的异常.比如程序本身有bug,比如程序打印时打印机没有纸了,比如内存不足.为了解决这些异常,我们需要知道异常发生的原因.对于一些常见的异常,我们还可以提供一定的应对预案.C语言中的异常处理是简单的通过函数返回值来实现的,但返回值代表的含义往往是由惯例决定的.程序员需要查询大量的资料,才可能找到一个模糊的原因.面向对象语言,比如C++, Java, Python往往有更加复杂的异常处理机制.这里讨论Java中的异常处理机制. Java异常处理 异常处理 Java的异

  • python进阶教程之异常处理

    在项目开发中,异常处理是不可或缺的.异常处理帮助人们debug,通过更加丰富的信息,让人们更容易找到bug的所在.异常处理还可以提高程序的容错性. 我们之前在讲循环对象的时候,曾提到一个StopIteration的异常,该异常是在循环对象穷尽所有元素时的报错. 我们以它为例,来说明基本的异常处理. 一个包含异常的程序: 复制代码 代码如下: re = iter(range(5)) for i in range(100):     print re.next() print 'HaHaHaHa'

  • React工作流程及Error Boundaries实现过程讲解

    目录 什么是Error Boundaries 步骤1:捕获错误 步骤2:构造callback 执行callback 总结 这里简单讲解下React工作流程,后文有用.分为三步: 触发更新 render阶段:计算更新会造成的副作用 commit阶段:在宿主环境执行副作用 副作用有很多,比如: 插入DOM节点 执行useEffect回调 好了,让我们进入主题. 什么是Error Boundaries React提供了两个与错误处理相关的API: getDerivedStateFromError:静态

  • React之错误边界 Error Boundaries示例详解

    目录 引言 注意 实现 错误边界应该放置在哪? 未捕获错误(Uncaught Errors)该如何处理? 注意:自 React 15 的命名更改 引言 过去,组件内的代码异常会导致 React 的内部状态被破坏,产生可能无法追踪的错误.但 React 并没有提供一种优雅处理这些错误的方式,也无法从错误中恢复. 默认情况下,若一个组件在渲染期间(render)发生错误,会导致整个组件树全部被卸载,这当然不是我们期望的结果. 部分组件的错误不应该导致整个应用崩溃.为了解决这个问题,React 16

  • React错误边界Error Boundaries

    首先 我们先构建出问题的场景 我们创建一个react项目 然后在src下创建 components 文件夹目录 在下面创建一个 error.jsx 组件 参开代码如下 import React from "react"; export default class App extends React.Component{ constructor(props){ super(props); this.state = { } } render(){ return ( <div>

  • Swift进阶教程Mirror反射示例详解

    目录 元类型与.self AnyObject AnyClass Any type(Of:) self self在方法里面的作用 Self Swift Runtime Mirror Mirror的基本用法 Mirror的简单应用-JSON解析 Mirror源码解析 Enum Metadata探索 还原TargetEnumMetadata 还原TargetEnumDescriptor 相对偏移指针 打印枚举中的属性 Struct Metadata探索 获取结构体的属性 swift_getTypeBy

  • GO语言标准错误处理机制error用法实例

    本文实例讲述了GO语言标准错误处理机制error用法.分享给大家供大家参考.具体分析如下: 在 Golang 中,错误处理机制一般是函数返回时使用的,是对外的接口,而异常处理机制 panic-recover 一般用在函数内部. error 类型介绍 error 类型实际上是抽象了 Error() 方法的 error 接口,Golang 使用该接口进行标准的错误处理. 复制代码 代码如下: type error interface {  Error() string } 一般情况下,如果函数需要返

  • AngularJS入门教程之路由机制ngRoute实例分析

    本文实例讲述了AngularJS路由机制ngRoute.分享给大家供大家参考,具体如下: 引言 在我们介绍路由之前我们首先谈一下SPA,所以SPA就是我们现在经常说的单页应用single page APP,为了实现无刷新的视图切换我们之前的做法就是利用AJAX从后取出数据然后渲染在前台页面HTML中,但是AJAX有一个致命的缺点就是不能实现浏览器的后退按钮失效,为了解决这个问题我们通常使用hash,监听hashchange事件来进行视图切换,另一个方法是用HTML5的history API,通过

随机推荐