在我下面的例子中,为什么devtools控制台中会出现无限循环的错误?看起来好像是resetErrorBoundary()
导致useEffect
再次触发,反之亦然,导致无限循环,但我不明白为什么useEffect
即使在其依赖数组中有一个常量值也会继续运行。
This answer通过使用if语句显式地检查依赖数组值的更改来解决问题,但是useEffect
不应该自动执行吗?我认为这样的if语句是多余的。
https://codesandbox.io/p/github/adamerose/error-boundary-example/main?file=%2Fsrc%2FApp.jsx
import { useEffect } from "react";
import { ErrorBoundary } from "react-error-boundary";
function ThisComponentWillError() {
throw Error("SomeError");
}
function App() {
return (
<main>
<StandardErrorBoundary>
<ThisComponentWillError />
</StandardErrorBoundary>
</main>
);
}
function ErrorFallback({ error, resetErrorBoundary }) {
useEffect(() => {
resetErrorBoundary();
}, ["CONSTANT"]);
return (
<div>
<p>Something went wrong:</p>
<pre>{error.toString()}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
);
}
function StandardErrorBoundary({ children }) {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>{children}</ErrorBoundary>
);
}
export default App;
注意-这只是一个最小的例子。我的实际项目在依赖项中有location.pathname
,因为我想重置URL导航的错误,但我意识到无论我在依赖项数组中有什么,它都会无限循环。
1条答案
按热度按时间pgvzfuti1#
一种调试方法是检查正在使用的库的源代码。幸运的是
react-error-boundary
只是一个组件,相对来说检查起来更容易。你假设
ErrorFallback
组件在resetErrorBoundary
被调用时被重新渲染。相反,它被完全重新挂载。一旦重新挂载,所有效果将再次运行,因为它就像是新的第一次调用函数。下面是source code。我已经评论了不相关的部分:
因此,一旦调用了
resetErrorBoundary
。状态被重新初始化并变为{error:null}
。现在,在这种情况下,错误边界 Package 代码的子代码将被呈现而不是回退。在上述情况下,子树再次抛出错误,因此状态变为{error:null}
以外的值。再次调用ErrorBoundary
的render方法,这次调用的是Fallback component is rendered because this time
this。state.error不为null。因此完成循环,并继续。 PS:我能够通过运行一个带有空依赖项的
useEffect`来发现该组件正在被重新挂载。