React@16.x(18)错误边界

火影  金牌会员 | 2024-6-11 10:17:14 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 643|帖子 643|积分 1929

1,什么是错误边界

默认情况下,如果一个组件在**渲染期间(render)**发生错误,会导致整个组件树被全部卸载。
   全部卸载:指整个应用都被卸载,<div id="root"></div> 没有子元素了。
一般此时 React 会在控制台打印错误消息。
  举例:
  1. import React, { PureComponent } from "react";
  2. function ChildA() {
  3.     return (
  4.         <>
  5.             <h1>childA</h1>
  6.             <ChildB></ChildB>
  7.         </>
  8.     );
  9. }
  10. function ChildB() {
  11.     const obj = {};
  12.     console.log(obj.a.b);
  13.     return <h1>childB</h1>;
  14. }
  15. function ChildC() {
  16.     return <h1>childC</h1>;
  17. }
  18. export default class App extends PureComponent {
  19.     render() {
  20.         return (
  21.             <>
  22.                 <ChildA />
  23.                 <ChildC />
  24.             </>
  25.         );
  26.     }
  27. }
复制代码
错误边界
指的是一个自界说的组件,它可以捕获子组件在渲染期间发生的错误,并有本领阻止继续往上流传。
2,捕获子组件的错误

可以通过2个生命周期函数来捕获。
2.1,static getDerivedStateFromError

2.1.1,特点

1,它是一个静态函数
2,运行时间点:渲染子组件的过程中,发生错误之后,更新页面之前。
3,该函数返回一个对象, React 会用该对象的属性覆盖掉当前组件的 state。
   不能利用 this.setState(),是因为它是静态函数。
  4,通常,该函数用于改变状态。
   也就是说,通过改变状态:选择不渲染出错的子组件,而是渲染指定的内容。
  2.1.2,举例

新增一个组件
  1. import React, { Component } from "react";
  2. export default class ErroBound extends Component {
  3.     state = {
  4.         hasError: false,
  5.     };
  6.     static getDerivedStateFromError(error) {
  7.         return {
  8.             hasError: true,
  9.         };
  10.     }
  11.     render() {
  12.         if (this.state.hasError) {
  13.             return <div>错误了</div>;
  14.         }
  15.         return this.props.children;
  16.     }
  17. }
复制代码
修改上面的例子:
  1. export default class App extends PureComponent {
  2.     render() {
  3.         return (
  4.             <>
  5.                 <ErroBound>
  6.                     <ChildA></ChildA>
  7.                 </ErroBound>
  8.                 <ChildC></ChildC>
  9.             </>
  10.         );
  11.     }
  12. }
复制代码
这样就可以捕获到报错的组件,不影响组件 ChildC 的正常渲染了。
2.2,componentDidCatch

2.2.1,特点

1,实例的方法。
2,运行时间点:渲染子组件的过程中,发生错误更新页面之后。因为时间点靠后,以是不太会在该函数中改变状态(固然这样利用没有标题。)
3,通常用于记录错误日记举行上报。
2.2.2,举例

  1. // 其他代码不变。
  2. export default class ErroBound extends Component {
  3.     // error 是错误对象。
  4.     // info 是一个多层级的对象,标记报错在哪个组件了。
  5.     componentDidCatch(error, info) {
  6.         this.setState({
  7.             hasError: true,
  8.         });
  9.     }
  10. }
复制代码
3,错误边界组件无法捕获的错误

3.1,自身的错误

3.2,异步的错误

比如,将 ChildB 组件做如下更改,初次渲染没有标题。1s 之后就会报错。
  1. function ChildB() {
  2.     setTimeout(() => {
  3.         const obj = {};
  4.         console.log(obj.a.b);
  5.     }, 1000);
  6.     return <h1>childB</h1>;
  7. }
复制代码
3.3,事件中的错误

比如,将 ChildB 组件做如下更改,初次渲染没有标题。点击就会报错。
  1. function ChildB() {
  2.     return (
  3.         <h1
  4.             onClick={() => {
  5.                 const obj = {};
  6.                 console.log(obj.a.b);
  7.             }}
  8.         >
  9.             childB
  10.         </h1>
  11.     );
  12. }
复制代码
因为这2个生命周期函数,仅会在首次渲染子组件期间执行,以是异步的错误就捕获不到了。
一句话总结:仅处置惩罚子组件渲染期间的同步错误

以上。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表