亲宝软件园·资讯

展开

React 错误边界

凌辰亦梦 人气:0

我们为什么需要错误边界

在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<PropsType, StateType> {
    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 <div>
                <h1>{`Error:${this.state.Error?.message}`}</h1>
                <details style={{whiteSpace: 'pre-wrap'}}>
                    {this.state.ErrorInfo?.componentStack}
                </details>
            </div>;
        }
        return this.props.children;
    }
}

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

使用方式如下:

//main.tsx
import ReactDOM from 'react-dom/client';
import {ErrorBoundary} from './ErrorBoundary.jsx';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
    <ErrorBoundary>
        <App/>
    </ErrorBoundary>
);
//app.tsx
import * as React from 'react';
function App() {
    const [count, setCount] = useState(0);
    if (count>0){
        throw new Error('count>0!');
    }
    return (
        <div>
            <button onClick={() => setCount((count) => count + 1)}>
                count is {count}
            </button>
        </div>
    );
}
export default App;

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

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

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

加载全部内容

相关教程
猜你喜欢
用户评论