🔱React查漏补缺-错误处理🔱

在构建应用时,错误是不可避免的。即使采用最佳的代码实践,运行时也可能会出现意外错误,导致应用崩溃。因此,处理错误是非常重要的。本文就来看看如何在 React 中捕获和处理错误,以及更强大的 React 错误处理方式!

当在React应用程序中处理错误时,你可以采取以下几种方法:

try-catch

在使用JavaScript时,可以使用try-catch块来捕获和处理错误。你可以将可能引发错误的代码放在try块中,并在catch块中处理异常情况。例如:

js 复制代码
try {
  // 可能引发错误的代码
} catch (error) {
  // 处理错误
}

try...catch仅适用于命令式代码,例如数据获取;而不是适用于声明式代码,例如在组件中编写的 JSX 就是声明式代码。那该如何在 React 中捕获错误呢?在 React 16 中,引入了一个新概念:React Error Boundary。下面来看一下它是什么,以及如何使用。

Error Boundary

React Error Boundary (错误边界)是 React 应用中错误处理的一种方式。它是一个 React 组件,可以捕获子组件树中任何位置的 JavaScript 错误,并记录这些错误,显示一个备选 UI,而不是一个崩溃的组件树(白屏)。它们就像一个 JavaScript 的 catch {} 块,但是只针对组件。

我们可以在整个应用范围内设置错误边界,也可以在各个组件上进行更细粒度的控制。需要注意的是,错误边界只会捕获渲染时、生命周期方法和构造函数中的错误,但不会捕获以下错误:

  • 事件处理(对于这种情况,需要使用常规的 try/catch 块)
  • 异步代码(例如,setTimeout 或 requestAnimationFrame 回调函数)
  • 服务端渲染
  • 错误发生在错误边界本身而不是其子组件中时

错误边界是在 React v16 中引入的,要使用错误边界,需要定义一个类组件,并添加以下生命周期方法之一或两个:

  • getDerivedStateFromError(): 这个生命周期方法在错误抛出后渲染备选 UI。它在渲染阶段被调用,所以不允许有副作用。
  • componentDidCatch(): 这个方法用于记录错误信息。它在提交阶段被调用,所以可以执行副作用。

下面来看一个 ErrorBoundary 类组件的例子,它实现了 getDerivedStateFromError() 和 componentDidCatch() 生命周期方法:

jsx 复制代码
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
​
  static getDerivedStateFromError(error) {
    // 更新 state,下一次渲染将展示备选 UI。
    return { hasError: true };
  }
​
  componentDidCatch(error, errorInfo) {
    console.log(error, errorInfo);
  }
​
  render() {
    if (this.state.hasError) {
      // 可以渲染任意自定义的备选 UI
      return <h1>出错啦!</h1>;
    }
​
    return this.props.children; 
  }
}
​
// 在组件中使用
class App extends React.Component {
  render() {
    return (
      <ErrorBoundary>
        <MyComponent />
      </ErrorBoundary>
    );
  }
}

这里定义了一个名为ErrorBoundary的错误边界组件。它的构造函数初始化了状态对象,并设置 hasError 属性为 false,表示当前没有发生错误。

  • getDerivedStateFromError() 方法在捕获到错误时会被调用。它接收一个 error 对象作为参数,并返回一个新的状态对象,将 hasError 属性设置为 true,以便在下一次渲染时展示备选的 UI。
  • componentDidCatch() 方法在捕获到错误后会被调用。在这个例子中,将错误和错误信息输出到控制台。

在 render() 方法中,根据 hasError 的值来决定渲染原始子组件还是备选的 UI。如果 hasError 为 true,则渲染 <h1>出错啦!</h1>,否则渲染原始子组件。在组件中使用错误边界时,将需要进行错误边界保护的组件包裹在 组件中即可。

在React组件中,我们可以使用 Error Boundary 来包裹任何组件,这样就不会因为一个小组件的崩溃,而导致整个组件崩溃,致使出现白屏。只有出现错误的组件处不能正常渲染,而是渲染备选 UI。也方便我们快速查找是哪个组件出了问题。

react-error-boundary

react-error-boundary是一个由社区维护的 React 错误边界工具,它简化了在 React 应用中实现错误边界的过程。使用 react-error-boundary 可以更加方便地捕获和处理组件树中的错误。

通过 react-error-boundary,你可以使用一个高阶组件 ErrorBoundary 来包装你的组件,并在需要时处理错误。它提供了一些灵活的方式来定义错误处理行为,以及在错误发生时展示备用 UI。与手动实现错误边界相比,使用 react-error-boundary 可以减少重复代码,并提供更清晰的 API。

react-error-boundary 提供了一些可用于自定义行为和处理错误的 props。以下是它的一些主要 props:

  • FallbackComponent:用于指定一个自定义组件,在错误边界内发生错误时进行渲染。它提供了灵活性,可以创建一个视觉上吸引人且信息丰富的用户界面来显示错误,并提供任何必要的操作。
  • fallbackRender:类似于 FallbackComponent,该属性用于定义一个自定义的渲染函数来渲染错误回退界面。它提供了对渲染过程的更多控制,并允许进行更高级的错误处理逻辑。
  • onError:其接受一个回调函数,在错误边界捕获到错误时调用该函数,并传递错误对象和组件堆栈跟踪信息。它使我们能够执行额外的操作,例如记录错误或将错误报告发送到外部服务。
  • onReset:其接受一个回调函数,在错误边界成功重置后触发。它可以用于执行清理操作或在错误恢复后更新组件的状态。
  • fallbackProps:允许向 FallbackComponent 或 fallbackRender 函数传递额外的 props。它可以用于提供上下文或附加数据给错误回退界面。
  • retry:布尔值,确定错误边界是否允许重试导致错误的操作。当设置为 true 时,resetErrorBoundary 函数可以从错误回退界面中调用以重试操作。

以下是一个简单的示例,展示了如何使用 react-error-boundary

jsx 复制代码
import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
​
// 自定义错误 UI 组件
function ErrorFallback({ error, resetErrorBoundary }) {
  return (
    <div>
      <h2>Something went wrong:</h2>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}
​
// 需要进行错误边界处理的组件
function MyComponent({ shouldThrowError }) {
  if (shouldThrowError) {
    throw new Error('Error thrown from MyComponent');
  }
  return <h1>Hello, World!</h1>;
}
​
function App() {
  return (
    <ErrorBoundary
      FallbackComponent={ErrorFallback} // 指定错误时展示的 UI 组件
      onReset={() => console.log('Error boundary reset!')} // 定义重置错误边界时的回调函数
      onError={(error, info) => console.log('Error caught by error boundary:', error, info)} // 定义捕获错误时的回调函数
    >
      <MyComponent shouldThrowError={true} />
    </ErrorBoundary>
  );
}
​
export default App;

在这个示例中,我们使用 ErrorBoundary 组件包装了 MyComponent 组件,并指定了在错误发生时展示的备用 UI 组件 ErrorFallback。我们还可以通过 onResetonError 属性来定义错误边界的行为。

相关推荐
Martin -Tang8 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发8 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
老码沉思录1 小时前
React Native 全栈开发实战班 - 第四部分:用户界面进阶之动画效果实现
react native·react.js·ui
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习