React 错误边界Error Boundary使用示例解析

 

我们为什么需要错误边界

在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:

 

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

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

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

以上就是React 错误边界Error Boundary使用示例解析的详细内容,更多关于React 错误边界的资料请关注编程宝库其它相关文章!

 nodejs生成文件并在前端下载最近遇到一个小需求,前端要下载一个json文件,内容是对应数据的json对象。看网上写的都太复杂了,只是下载一个小文件,只需要用到res.end()就够了。前 ...