服务器之家:专注于服务器技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - React - React 错误边界组件的处理

React 错误边界组件的处理

2022-02-28 16:23xuxiaowei React

这篇文章主要介绍了React 错误边界组件的处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这是react16的内容,并不是最新的技术,但是用很少被讨论,直到通过文档发现其实也是很有用的一部分内容,还是总结一下~

react中的未捕获的 js 错误会导致整个应用的崩溃,和整个组件树的卸载。从 react16 开始就是这样。但是同时react也引入了一个新的概念——错误边界。

定义,是什么

错误边界仍然是一种组件,可以捕获(打印或者其他方式)处理该组件的子组件树任何位置的 javascript 错误,并根据需要渲染出备用ui.

工作方式类似于try-catch,但是错误边界只用于 react 组件。

只有class组件能够成为错误边界组件。错误边界仅可以捕获子组件的错误,无法捕获自身的错误。

错误边界会在渲染期间,生命周期和整个组件树的构造函数中捕获错误。如果没有错误边界处理,渲染的还是崩溃的子组件树,这显然不是我们想要的。

通过一个例子来逐步演示要怎么用错误边界:

  1. export default class ErrorTest extends Component { 
  2.   constructor(props) { 
  3.     super(props); 
  4.   } 
  5.   render() { 
  6.     return ( 
  7.       <div> 
  8.         <BugCounter></BugCounter> 
  9.         <span>my name is dan</span> 
  10.       </div> 
  11.     ); 
  12.   } 
  13.  
  14. // Bug 报错组件 
  15. class BugCounter extends Component { 
  16.   constructor(props) { 
  17.     super(props); 
  18.     this.state = { 
  19.       counter: 0, 
  20.     }; 
  21.   } 
  22.   click = () => { 
  23.     this.setState(({ counter }) => ({ counter: counter + 1 })); 
  24.   }; 
  25.   render() { 
  26.     if (this.state.counter === 5) { 
  27.       throw new Error("crashed!"); 
  28.     } 
  29.     return ( 
  30.       <div> 
  31.         <h3 onClick={this.click}>{this.state.counter}</h3> 
  32.       </div> 
  33.     ); 
  34.   } 

上面代码的渲染结果(忽略样式):

React 错误边界组件的处理

点击数字0,会逐步递增。但是数字等于5的时候,组件会抛出一个error:

React 错误边界组件的处理

error会引起整个demo的崩溃,连外部的<span>my name is dan</span>也显示不出来了,这时还没有添加错误边界。

生产模式下,会直接白屏,并在控制台报错:

React 错误边界组件的处理

getderivedstatefromerror & componentdidcatch

需要一个错误边界来处理这种崩溃。如何定义一个错误边界?

定义一个组件,并实现static getderivedstatefromerror() 或者componentdidcatch() 生命周期方法(可以都实现或者选择其一)。这个组件就会变成一个错误边界。

关于这两个生命周期函数,可以通过链接查看,总结如下:

  1. componentDidCatch(error, info) 

error是抛出的错误对象,而info则包含了组件引发错误的栈信息。函数在提交阶段被调用。是可以执行副作用的。

  1. static getDerivedStateFromError(error) 

在子组件抛出错误后调用,会将抛出的错误作为参数。需要返回一个值,以更新state。该函数在渲染阶段调用,不允许出现副作用。如果在捕获错误后需要执行副作用操作,应该在componentdidcatch中进行。

制作错误边界组件

可以使用组合的方式,在要使用的组件上面添加一个错误边界组件包裹一层。该组件需要这些效果:

  • 捕获子组件错误,组件内部记录出错状态
  • 在出错状态下显示备用ui,在正常状态下显示子组件

那么就可以像这样:

  1. class ErrorBoundary extends React.Component { 
  2.   constructor(props) { 
  3.     super(props); 
  4.     this.state = { hasError: false }; 
  5.   } 
  6.  
  7.   static getDerivedStateFromError(error) { 
  8.     // 更新 state 使下一次渲染能够显示降级后的 UI 
  9.     return { hasError: true }; 
  10.   } 
  11.  
  12.   componentDidCatch(error, errorInfo) { 
  13.     // 你同样可以将错误日志上报给服务器 
  14.     logErrorToMyService(error, errorInfo); 
  15.   } 
  16.  
  17.   render() { 
  18.     if (this.state.hasError) { 
  19.       // 你可以自定义降级后的 UI 并渲染 
  20.       return <h1>Something went wrong.</h1>; 
  21.     } 
  22.  
  23.     return this.props.children;  
  24.   } 

捕获到错误之后的副作用是自定义的,上传服务器,或者用state记录再显示在页面上:

  1. componentDidCatch(error, errorInfo) { 
  2.   // Catch errors in any components below and re-render with error message 
  3.   this.setState({ 
  4.     error: error, 
  5.     errorInfo: errorInfo 
  6.   }) 

捕获处理

加上所有代码,将有问题的组件用错误边界的组件包裹起来,看看结果:

  1. import { Component } from "react"
  2.  
  3. export default class ErrorTest extends Component { 
  4.   render() { 
  5.     return ( 
  6.       <div> 
  7.         <ErrorBoundary> 
  8.           <BugCounter></BugCounter> 
  9.         </ErrorBoundary> 
  10.         <span>my name is dan</span> 
  11.       </div> 
  12.     ); 
  13.   } 
  14.  
  15. // Bug 报错组件 
  16. class BugCounter extends Component { 
  17.   constructor(props) { 
  18.     super(props); 
  19.     this.state = { 
  20.       counter: 0, 
  21.     }; 
  22.   } 
  23.   click = () => { 
  24.     this.setState(({ counter }) => ({ counter: counter + 1 })); 
  25.   }; 
  26.   render() { 
  27.     if (this.state.counter === 5) { 
  28.       throw new Error("crashed!"); 
  29.     } 
  30.     return ( 
  31.       <div> 
  32.         <h3 onClick={this.click}>{this.state.counter}</h3> 
  33.       </div> 
  34.     ); 
  35.   } 
  36.  
  37. // 错误边界处理组件 
  38. class ErrorBoundary extends Component { 
  39.   constructor(props) { 
  40.     super(props); 
  41.     this.state = { hasError: false }; 
  42.   } 
  43.  
  44.   static getDerivedStateFromError(error) { 
  45.     // 更新 state 使下一次渲染能够显示降级后的 UI 
  46.     return { hasError: true }; 
  47.   } 
  48.  
  49.   render() { 
  50.     if (this.state.hasError) { 
  51.       // 你可以自定义降级后的 UI 并渲染 
  52.       return <h1>Something went wrong.</h1>; 
  53.     } 
  54.  
  55.     return this.props.children; 
  56.   } 

抛出异常在开发模式下依然是报错的,但是在使用yarn build之后,再通过http-server挂起来之后,访问生产的页面:

React 错误边界组件的处理

可以看到,虽然因为throw error控制台出错,但是my name is dan的显示并没有被影响,也就是说,错误边界内部的子组件错误没有影响到外部其他组件和元素。

作用范围

错误边界用于处理子组件生命周期和渲染函数上的错误,对于事件处理器,不会在渲染期间触发,对于事件处理器抛出的异常应该用try catch

错误边界无法捕获这些场景中的错误:

  • 事件处理
  • 异步代码
  • 服务端渲染
  • 错误边界自身抛出的错误(非子组件)

关于错误边界,一个 react的官方demo值得尝试:

https://codepen.io/gaearon/pen/wqvxga?editors=0010

参考:

https://zh-hans.reactjs.org/docs/error-boundaries.html

https://zh-hans.reactjs.org/docs/react-component.html

https://codepen.io/gaearon/pen/wqvxGa?editors=0010

到此这篇关于react 错误边界组件的处理的文章就介绍到这了,更多相关react 错误边界内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/xuxiaowei/p/14645136.html

延伸 · 阅读

精彩推荐
  • React使用hooks写React组件需要注意的5个地方

    使用hooks写React组件需要注意的5个地方

    这篇文章主要介绍了使用hooks写React组件需要注意的5个地方,帮助大家更好的理解和学习使用React组件,感兴趣的朋友可以了解下...

    forrest酱8702022-02-24
  • React详解对于React结合Antd的Form组件实现登录功能

    详解对于React结合Antd的Form组件实现登录功能

    这篇文章主要介绍了详解对于React结合Antd的Form组件实现登录功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    浮生离梦6542022-02-23
  • React浅谈react路由传参的几种方式

    浅谈react路由传参的几种方式

    这篇文章主要介绍了浅谈react路由传参的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    glorydx4582022-02-20
  • React一看就懂的ReactJs基础入门教程-精华版

    一看就懂的ReactJs基础入门教程-精华版

    现在最热门的前端框架有AngularJS、React、Bootstrap等。自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略...

    雲霏霏9262022-02-22
  • React详解react setState

    详解react setState

    这篇文章主要介绍了react setState的相关资料,帮助大家更好的理解和学习使用react,感兴趣的朋友可以了解下...

    一个前端王4942022-02-27
  • ReactReact+Ant Design开发环境搭建的实现步骤

    React+Ant Design开发环境搭建的实现步骤

    这篇文章主要介绍了React+Ant Design开发环境搭建的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    qq_3341488311802022-02-24
  • React详解react应用中的DOM DIFF算法

    详解react应用中的DOM DIFF算法

    这篇文章主要介绍了react应用中的DOM DIFF算法,帮助大家更好的理解和学习使用react,感兴趣的朋友可以了解下...

    time_w6232022-02-25
  • Reactreact hooks入门详细教程

    react hooks入门详细教程

    这篇文章主要介绍了react hooks入门详细教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考...

    抱素_6832022-02-23