1、React中错误异常捕获
在 React 中,可以通过 Error Boundaries
(错误边界)来捕获错误异常。Error Boundaries
是一种 React 组件,它可以在其子组件树的渲染期间捕获 JavaScript 异常,并且可以渲染出备用 UI。React 提供了两个生命周期方法来处理错误边界:componentDidCatch
和 getDerivedStateFromError
。
其中,componentDidCatch
生命周期方法在错误边界内的任何子组件抛出错误时被调用。它接收两个参数:error
和 info
。error
参数表示抛出的错误,info
参数包含有关组件引发错误的组件堆栈的信息。通常情况下,此方法将记录错误并更新组件的状态以显示备用 UI。
componentDidCatch方法:用于处理错误异常,当子组件抛出错误时,React会在Error Boundary中调用componentDidCatch方法。在该方法中可以实现错误信息的记录和展示等逻辑。
getDerivedStateFromError方法:会在componentDidCatch方法调用之后调用,用于更新state中的数据。该方法可以返回一个对象来更新组件的状态。
下面是一个简单的错误边界的示例:
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
// getDerivedStateFromError从错误信息中进行状态的浅合并更新。
static getDerivedStateFromError(error) {
// 更新 state 以显示备用 UI
return { hasError: true };
}
componentDidCatch(error, info) {
// 记录错误
console.log(error, info);
}
render() {
if (this.state.hasError) {
// 显示备用 UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
在上面的示例中,ErrorBoundary
组件包装了其子组件,并提供了备用 UI。如果其中的任何子组件引发错误,则会调用 componentDidCatch
生命周期方法并更新状态以显示备用 UI。
然后,可以将 ErrorBoundary
组件包装在任何需要捕获错误异常的组件中:
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
function App() {
return (
<div>
<h1>Hello, world!</h1>
<ErrorBoundary>
<ComponentThatMayThrowAnError />
</ErrorBoundary>
</div>
);
}
在上面的示例中,ComponentThatMayThrowAnError
组件可能会抛出错误,因此将其包装在 ErrorBoundary
组件中,以确保错误得到捕获和处理。
注意⚠️:
1、错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误。
2、错误边界无法捕获以下场景中产生的错误:
- 事件处理(了解更多)
- 异步代码(例如
setTimeout
或requestAnimationFrame
回调函数) - 服务端渲染
- 它自身抛出来的错误(并非它的子组件)
3、错误边界的工作方式类似于 JavaScript 的 catch {}
,不同的地方在于错误边界只针对 React 组件。只有 class 组件才可以成为错误边界组件
4、错误边界仅可以捕获其子组件的错误,它无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,这也类似于 JavaScript 中 catch {}
的工作机制。
5、React 不需要错误边界来捕获事件处理器中的错误。与 render 方法和生命周期方法不同,事件处理器不会在渲染期间触发
6、如果你需要在事件处理器内部捕获错误,使用普通的 JavaScript try
/ catch
语句。
函数组件中怎样进行错误异常捕获?
在函数组件中,可以使用useErrorBoundary
hook来定义一个错误边界。它返回一个包含两个元素的数组:错误状态和错误信息。当发生错误时,错误状态会被设置为true,错误信息会被更新为错误对象。
useErrorBoundary
是一个自定义的 React Hook,用于在函数组件中捕获错误异常并处理。它的实现原理基于 React 的错误边界机制,利用了 componentDidCatch
生命周期方法。
使用 useErrorBoundary
需要传入一个函数作为错误处理函数。当函数组件中发生错误时,错误处理函数会被调用并传入错误对象。同时,useErrorBoundary
会返回一个布尔值,表示组件是否处于错误状态。
以下是一个简单的示例,展示了如何使用 useErrorBoundary
捕获错误异常:
import React, { useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
if (count === 2) {
throw new Error('Something went wrong');
}
}
function handleError(error) {
console.error(error);
}
const [hasError, resetErrorBoundary] = useErrorBoundary(handleError);
return (
<div>
{hasError ? (
<div>
<p>Something went wrong.</p>
<button onClick={resetErrorBoundary}>Reset</button>
</div>
) : (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
)}
</div>
);
}
在这个示例中,当 count
的值等于 2 时,会抛出一个错误异常。useErrorBoundary
会捕获这个异常,并调用 handleError
函数进行处理。如果 hasError
的值为 true
,则说明组件处于错误状态,可以通过 resetErrorBoundary
函数重置组件并清除错误状态。
2、浏览器中错误异常捕获
浏览器提供了一些方法来捕获 JavaScript 运行时的错误异常,包括以下几种:
- try-catch语句:用于捕获同步代码块中的错误异常。
- window.onerror:用于捕获全局的错误异常,包括语法错误、网络请求错误等,但是无法捕获异步错误异常。
- window.addEventListener('error'):用于捕获全局的错误异常,包括语法错误、网络请求错误等,但是无法捕获异步错误异常。
- window.addEventListener('unhandledrejection'):用于捕获 Promise 中未被 catch 的错误异常。
下面是具体的示例: