React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > react错误边界ErrorBoundary

react错误边界ErrorBoundary的问题解决

作者:光影少年

错误边界是React提供的一种,用于捕获其子组件树中的JavaScript运行时错误,并显示降级UI,而不是让整个应用崩溃,本文就来详细的介绍一下该问题的解决,感兴趣的可以了解一下

ErrorBoundary(错误边界)是 React 提供的一种错误捕获机制,用于捕获其子组件树中的 JavaScript 运行时错误,并显示降级 UI,而不是让整个应用崩溃。

1. ErrorBoundary 能解决什么问题?

假设有个组件:

function UserInfo() {
  throw new Error('获取用户信息失败');

  return <div>用户信息</div>;
}

如果没有 ErrorBoundary:

<App>
  <UserInfo />
</App>

页面会直接白屏:

Error: 获取用户信息失败

有 ErrorBoundary:

<ErrorBoundary>
  <UserInfo />
</ErrorBoundary>

页面显示:

系统异常,请稍后重试

而不会导致整个 React 应用崩溃。

2. ErrorBoundary 能捕获哪些错误?

✅ 能捕获:

例如:

class Demo extends React.Component {
  render() {
    throw new Error('render error');
  }
}

3. ErrorBoundary 不能捕获哪些错误?

❌ 事件函数错误

<button
  onClick={() => {
    throw new Error('点击异常');
  }}
>
  点击
</button>

不会进入 ErrorBoundary。

需要自己 try-catch:

const handleClick = () => {
  try {
    throw new Error('点击异常');
  } catch (err) {
    console.log(err);
  }
};

❌ 异步代码错误

useEffect(() => {
  setTimeout(() => {
    throw new Error('异步错误');
  }, 1000);
}, []);

不会被捕获。

应该:

useEffect(() => {
  setTimeout(() => {
    try {
      throw new Error('异步错误');
    } catch (err) {
      console.log(err);
    }
  }, 1000);
}, []);

❌ Promise 错误

fetch('/api')
  .then(res => res.json())
  .catch(err => {
    console.log(err);
  });

需要手动 .catch()

4. ErrorBoundary 实现原理

React 提供两个生命周期:

static getDerivedStateFromError

发生错误时更新状态。

static getDerivedStateFromError(error) {
  return {
    hasError: true
  };
}

componentDidCatch

记录错误日志。

componentDidCatch(error, errorInfo) {
  console.log(error);
  console.log(errorInfo);
}

5. 完整实现

import React from 'react';

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      hasError: false
    };
  }

  static getDerivedStateFromError(error) {
    return {
      hasError: true
    };
  }

  componentDidCatch(error, errorInfo) {
    console.error('错误信息:', error);
    console.error('组件堆栈:', errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>页面发生异常</h1>;
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

使用:

<ErrorBoundary>
  <UserInfo />
</ErrorBoundary>

6. React 18 + TypeScript 写法

import React, { Component, ReactNode } from 'react';

interface Props {
  children: ReactNode;
}

interface State {
  hasError: boolean;
}

class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);

    this.state = {
      hasError: false
    };
  }

  static getDerivedStateFromError(): State {
    return {
      hasError: true
    };
  }

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    console.error(error);
    console.error(info);
  }

  render() {
    if (this.state.hasError) {
      return <div>页面异常</div>;
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

7. 函数组件如何实现?

React 官方目前没有 Hook 版 ErrorBoundary。

函数组件通常借助:

安装:

npm install react-error-boundary

使用:

import { ErrorBoundary } from 'react-error-boundary';

function ErrorFallback({ error }) {
  return (
    <div>
      <p>页面异常</p>
      <pre>{error.message}</pre>
    </div>
  );
}

function App() {
  return (
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <UserInfo />
    </ErrorBoundary>
  );
}

8. 项目中的最佳实践

全局错误边界

ReactDOM.createRoot(document.getElementById('root')).render(
  <ErrorBoundary>
    <App />
  </ErrorBoundary>
);

页面级错误边界

<ErrorBoundary>
  <PerformanceReport />
</ErrorBoundary>

模块级错误边界

<ErrorBoundary>
  <EchartsPanel />
</ErrorBoundary>

这样即使图表崩溃:

<EchartsPanel />

也不会影响:

<Table />
<Form />
<Menu />

9. 云鉴性能平台中的应用场景

根据你目前的 React + Ant Design + ECharts 项目,可以这样使用:

<ErrorBoundary>
  <PerformanceOverview />
</ErrorBoundary>

<ErrorBoundary>
  <CpuCompareChart />
</ErrorBoundary>

<ErrorBoundary>
  <IssueTracking />
</ErrorBoundary>

例如:

const data = undefined;

data.map(item => item.name);

出现:

Cannot read properties of undefined (reading 'map')

此时:

不会整页白屏。

10. 面试高频问题

Q:ErrorBoundary 是什么?

答:React 提供的错误捕获机制,用于捕获组件树中的运行时异常并展示降级 UI,避免整个应用崩溃。

Q:实现 ErrorBoundary 必须使用什么组件?

答:必须使用 Class Component,因为依赖:

static getDerivedStateFromError()

componentDidCatch()

函数组件不能直接实现。

Q:ErrorBoundary 能捕获事件错误吗?

答:不能。

onClick
onChange
setTimeout
Promise
async/await

中的异常需要自行处理。

一句话总结:

ErrorBoundary = React 的“try...catch(组件级)”,专门用于捕获渲染阶段和生命周期中的错误,防止页面白屏。

到此这篇关于react错误边界ErrorBoundary的问题解决的文章就介绍到这了,更多相关react错误边界ErrorBoundary内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文