Error Boundaries 为啥捕获不到异步错误?
我在 React 里写了 Error Boundary,同步错误能正常捕获,但组件里用 setTimeout 抛出的错误却没被 catch 到,这是为啥?
我试过把 throw new Error('async') 放在 useEffect 里和 setTimeout 里,结果 Error Boundary 都没生效,控制台直接报红了。
我的 Error Boundary 写法大概是这样的:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.log('Caught an error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
然后子组件里这样触发错误:
useEffect(() => {
setTimeout(() => {
throw new Error('Oops!');
}, 1000);
}, []);
这到底是不是 Error Boundary 的限制?还是我哪里写错了?
要解决这个问题,你可以在 setTimeout 或 useEffect 内部手动处理错误,试试这样改写:
或者把可能出错的异步操作放到一个函数里,并用 try...catch 包装起来。这种情况下,虽然 Error Boundary 不会捕获错误,但至少你能控制错误的处理方式。
说到这,其实这也是 React 的一个设计选择。异步错误通常需要更细粒度的处理,而不是全局的边界捕获。开发中遇到这种情况,确实有点烦人,但想想也有道理。总之,记住这点特性就能避免掉坑了。