ErrorBoundary错误边界
https://zh-hans.reactjs.org/docs/error-boundaries.html

  1. ErrorBoundary 捕获组件错误,处理组件渲染错误;仅处理渲染子组件的同步错误
    1. 组件渲染期间的错误
    2. 生命周期方法里面的错误
    3. 整个组件树的错误
  2. 父组件捕获子组件的错误,不能捕获当前组件的错误
  3. ErrorBoundary不能捕获的错误
    1. 组件的自身错误
    2. 异步错误,比如定时器 setTimeout 、Promise回调函数
    3. 事件中的错误,比如click事件中发生的错误
    4. 服务端渲染错误
    5. 组件自己抛出来的错误,不是子组件

static getDerivedStateFromError
子组件引发错误后,将调用此生命周期方法;

getDerivedStateFromError 接收作为参数抛出的错误,并且应返回值以更新状态
https://zhuanlan.zhihu.com/p/103487621

ErrorBoundary

全局的错误处理,用 ErrorBoundary 包裹

  • 父组件监听子组件的错误,不能监听组件自己的错误
  • 遇到事件内部的错误,不能捕获到
  • setTimeout,异步函数内部的错误,不能捕获到

ErrorBoundary.js

  1. import React, { Component } from 'react';
  2. import { string } from 'prop-types';
  3. import { Alert } from 'antd';
  4. class ErrorBoundary extends Component {
  5. constructor(props) {
  6. super(props);
  7. this.state = { isError: null };
  8. }
  9. // 子组件被渲染发生错误之后 且页面更新之前,该函数才会被执行
  10. static getDerivedStateFromError() {
  11. // 返回的对象会覆盖当前的 state,让下一次渲染能够显示降级后的 UI
  12. return { isError: true };
  13. }
  14. // 子组件渲染发生错误且页面更新之后,用于记录错误信息
  15. // error 抛出的错误
  16. // errorInfo 带有 componentStack key的对象,包含组件的错误栈信息
  17. componentDidCatch(error, errorInfo) {
  18. this.setState({ isError: true });
  19. window.console.error('error', error);
  20. window.console.error('errorInfo', errorInfo);
  21. }
  22. render() {
  23. const { children, message } = this.props;
  24. if (this.state.isError) {
  25. return <Alert message="加载错误" description={message} type="error" showIcon />;
  26. }
  27. return children;
  28. }
  29. }
  30. ErrorBoundary.propTypes = {
  31. message: string,
  32. };
  33. ErrorBoundary.defaultProps = {
  34. message: '出错啦,请联系管理员',
  35. };
  36. export default ErrorBoundary;

BaseLayout

Layout布局组件,处理全局错误
Layout.js

  1. import ErrorBoundary from './ErrorBoundary'
  2. function BaseLayout({children}) {
  3. return (
  4. <ErrorBoundary>
  5. {children}
  6. </ErrorBoundary>
  7. )
  8. }
  9. export default BaseLayout;

react-error-boundary

https://www.npmjs.com/package/react-error-boundary

  1. yarn add react-error-boundary
  2. import { useErrorHandler } from 'react-error-boundary';

useErrorHandler

  1. function useErrorHandler() {
  2. const [error, setError] = React.useState(null);
  3. if (error != null) throw error;
  4. return setError;
  5. }
  6. // 使用
  7. function Foo() {
  8. const handleError = useErrorHandler();
  9. fetchMayError().catch(handleError);
  10. return <div></div>;
  11. }

How to use ‘useErrorHandler()’ in React?
https://stackoverflow.com/questions/64233408/how-to-use-useerrorhandler-in-react