• 当面试官让我回答React和Vue框架的区别......


    我们为什么需要错误边界

    在React组件中可能会由于某些JavaScript错误,导致一些无法追踪的错误,导致应用崩溃。部分 UI 的 JavaScript 错误不应该导致整个应用崩溃。为此,React引入了错误边界(Error Boundary)的概念:可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。

    而在React16以后,未捕获的错误会导致React组件树的卸载,也就是白屏。所以某些情况下还是非常需要使用Error Boundary组件来避免这种比较严重的问题。

    如何使用错误边界组件

    按照React官方的约定,一个类组件定义了static getDerivedStateFromError()componentDidCatch() 这两个生命周期函数中的任意一个(或两个),即可被称作ErrorBoundary组件,实现错误边界的功能。

    其中,getDerivedStateFromError方法被约定为渲染备用UI,componentDidCatch方法被约定为捕获打印错误信息。

    具体的实现如下:

    //ErrorBoundary.tsx
    import * as React from 'react';
    ​
    interface PropsType {
        children: React.ReactNode;
    }
    ​
    interface StateType {
        hasError: boolean,
        Error?: null | Error,
        ErrorInfo?: null | React.ErrorInfo,
    }
    ​
    export class ErrorBoundary extends React.Component {
        constructor(props: PropsType) {
            super(props);
            this.state = {
                hasError: false,
                Error: null,
                ErrorInfo: null
          };
      }
        //控制渲染降级UI
        static getDerivedStateFromError(error: Error): StateType {
            return {hasError: true};
      }
        //捕获抛出异常
        componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
            //传递异常信息
            this.setState((preState) => 
              ({hasError: preState.hasError, Error: error, ErrorInfo: errorInfo})
          );//可以将异常信息抛出给日志系统等等//do something....
      }
    ​
        render() {
            //如果捕获到异常,渲染降级UI
            if (this.state.hasError) {
                return 
                   

    {`Error:${this.state.Error?.message}`}

                   
    {whiteSpace: 'pre-wrap'}}>                  {this.state.ErrorInfo?.componentStack}                
               
    ;      }        return this.props.children;  } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    实现ErrorBoundary组件后,我们只需要将其当作常规组件使用,将其需要捕获的组件放入其中即可。

    使用方式如下:

    //main.tsx
    import ReactDOM from 'react-dom/client';
    import {ErrorBoundary} from './ErrorBoundary.jsx';
    ​
    ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
        
            
        
    );
    ​ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    //app.tsx
    import * as React from 'react';
    ​
    function App() {
        const [count, setCount] = useState(0);
    ​
        if (count>0){
            throw new Error('count>0!');
      }
    ​
        return (
            
                       
     ); } ​ export default App;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    点击按钮后即可展示抛出异常时,应该渲染的降级UI:

    使用错误边界需要注意什么

    没有什么技术栈或者技术思维是银弹,错误边界看起来用得很爽,但是需要注意以下几点:

    • 错误边界实际上是用来捕获render阶段时抛出的异常,而React事件处理器中的错误并不会渲染过程中被触发,所以错误边界捕获不到事件处理器中的错误。React官方推荐使用try/catch来自行处理事件处理器中的异常。* 错误边界无法捕获异步代码中的错误(例如 setTimeout或 requestAnimationFrame回调函数),这两个函数中的代码通常不在当前任务队列内执行。* 目前错误边界只能在类组件中实现,也只能捕获其子组件树的错误信息。错误边界无法捕获自身的错误,如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,类似于JavaScript中的cantch的工作机制。* 错误边界无法在服务端渲染中生效,因为根本的渲染方法已经ReactDOM.createRoot().render()修改为了ReactDOM.hydrateRoot(), 而上面也提到了,错误边界捕获的是render阶段时抛出的异常。

    最后

    最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



    有需要的小伙伴,可以点击下方卡片领取,无偿分享

  • 相关阅读:
    Android WMS——WM窗口管理(八)
    2022/10/1——基于stm32mp157a的M4核LED灯实验
    微信小程序开发引入RUM,实现小程序监控
    ARM64 linux 中断处理--架构
    Java高级特性:泛型、集合框架和异常处理
    Hive知识梳理(好文)
    Mybatis中${}和#{}的区别
    【博客440】Linux netlink:用户态进程与内核态进程通信
    IDEA一键启动多个微服务
    Web & Electron 平台即时通讯产品的技术选型
  • 原文地址:https://blog.csdn.net/weixin_53312997/article/details/127679062