React之错误边界(Error Boundaries)详解

错误边界(Error boundaries)
从react v16开始,引入边界错误概念。

核心APIgetDerivedStateFromError
componentDidCatch
1. 目的:某些UI崩溃,不至于整个webapp崩溃
2. 注意:错误边界无法捕获如下场景的错误
事件处理
异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
服务端渲染
它自身抛出来的错误(并非它的子组件)
3.编写错误边界组件

import React, { Component } from 'react';

interface ErrorBoundaryProps { };
interface ErrorBoundaryState {
    hasError: boolean;
};

class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
    constructor(props: ErrorBoundaryProps) {
        super(props);
        this.state = {
            hasError: false
        };
    }

    static getDerivedStateFromError(error: Error) {
        // 更新 state 使下一次渲染能够显示降级后的 UI
        return { hasError: true };
    }

    componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
        // 你同样可以将错误日志上报给服务器
        console.group();
        console.log('ErrorBoundary catch a error:');
        console.info('error', error);
        console.info('error info', errorInfo);
        console.groupEnd()
    }


    render() {
        console.log('component ErrorBoundary render...');
        const { children } = this.props;
        const { hasError } = this.state;
        // return (
        //     <>
        //         {
        //             hasError ? 'Something Wrong' : children
        //         }
        //     </>

        // )
        if (hasError) {
            return 'Something wrong';
        } else {
            return children;
        }
    }
}
export default ErrorBoundary;


4.编写一个“错误组件”
点击按钮,触发+1,当counter为5时,抛出Error

import React, { Component } from 'react';

interface ErrorComponentProps { };
interface ErrorComponentState {
    counter: number;
};

class ErrorComponent extends Component<ErrorComponentProps, ErrorComponentState> {
    constructor(props: any) {
        super(props);
        this.state = {
            counter: 0
        }
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        // 事件处理的错误,ErrorBoundary无法捕捉
        // if (this.state.counter === 5) {
        //     throw new Error();
        // }
        this.setState({
            counter: this.state.counter + 1
        });

    }

    render() {
        console.log('component ErrorComponent render...');
        const { counter } = this.state;
        const { handleClick } = this;
        if (counter === 5) {
            throw new Error('counter creashed!');
        }
        return (
            <>
                <p>this component will throw Error when the counter equal to 5</p>
                <p>counter : {counter}</p>
                <button onClick={handleClick}>add</button>
            </>
        )
    }
}

export default ErrorComponent;


5. 组合

import React from 'react';

import ErrorBoundary from './component/ErrorBoundary';
import ErrorComponent from './component/ErrorBoundary/ErrorComponent';

function App() {
  return (
    <div className="App">
        <ErrorBoundary>
          <ErrorComponent />
        </ErrorBoundary>

    </div>
  );
}

export default App;


6.打包静态资源

不再devserver测试的原因是,在cra的配置中,webpack会捕捉Error并显示错误蒙版,不便于看到测试结果
在package.json添加字段"homepage": "."

7. yarn build


8. 找到index.html,测试吧!
 

猜你喜欢

转载自blog.csdn.net/m0_65121454/article/details/129927502