2022年前端React的100道面试题的第15题:错误边界

问题

React17 中错误边界(Error Boundaries)能正常捕获错误的场景有哪些?

选项

A. 绑定DOM的事件方法中的错误。

B. 异步代码中的错误。

C. 任意子组件树的渲染方法 render() 和所有生命周期方法中的错误。

D. 错误边界组件自身的错误。

答案

C

纠错

A. 绑定DOM的事件处理方法中的错误无法被捕获到。(因为在触发交互前,组件的生命周期和渲染都已经被执行。如果需要捕获事件的方法中的错误,需要使用 JS 的 try / catch 方法。)

B. 异步代码中的错误无法被捕获到。(包括 setTimeout、Promise 等,原因与A同理。)

D. 错误边界组件自身错误无法被捕获,而是会被上层的错误边界组件给获取。

解答

错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。

错误边界组件

在 class 组件中定义了 static getDerivedStateFromError()componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时,那么它就变成一个错误边界。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
​
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
​
  componentDidCatch(error, errorInfo) {
    logErrorToMyService(error, errorInfo);
  }
​
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

当抛出错误后,请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息。

备注:只有 class 组件才可以成为错误边界组件。

错误边界原理

当组织树种没有定义错误边界组件时,React16 之后的版本就会卸载掉报错的组件树。它和 try / catch 机制是完全一样的,假设有如下结构的4个组件:

  • CompA

    • CompB

      • CompC1

      • CompC2

在没有错误边界的情况下,我们在 CompC1 的 render() 中抛出一个 Error 后,会导致上面的所有组件都被卸载掉。这时我再加入上面定义的错误边界组件来 catch 错误,调整如下:

  • CompA

    • CompB

      • ErrorBoundary

        • CompC1

        • CompC2

同样在 CompC1 组件抛出错误时,CompC1 和 CompC2 会被卸载掉,并且会启用 ErrorBoundary 组件中的 render 内容错误信息。

错误信息

假设我们在 render() 中抛出一个 new Error('I crashed!') 的错误时,可以在 componentDidCatch(error, errorInfo) 方法中会获得对应的错误详细信息,这里的 errorInfo 中的 componentStack 为 React 提供的组件堆栈信息。

in BuggyCounter (created by App)
in ErrorBoundary (created by App)
in div (created by App)
in App

而 err 对象为原生的 Error 对象,使用 error.toString() 可以打印出具体的报错描述: I crashed!

资料

错误边界 – React

来源

搜索《考试竞技》微信小程序

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值