如果某个组件渲染了10次,并且有错误,则componentDidCatch()
将以相同的错误触发10次。目前,我正在捕获一个API请求以记录该错误,但是我只想将该错误记录为一次。
我的第一步虽然是保存自己的prevError
状态,然后检查传递给error
的{{1}}是否相同。但这是行不通的,因为componentDidCatch()
请求不是立即请求。其他一些生命周期事件通过了最新状态,但事实并非如此。我知道setState
会使用最新状态的回调,但是届时错误将始终等于setState()
。这就是我的意思:
prevError
我也不认为我可以以某种方式使用componentDidCatch(error, info) {
this.setState({ error: true });
const isNewError = (error.toString() !== this.state.prevError.toString());
// always true since setState is async
if (isNewError) {
logErrorToMyService(error, info); // should only run once
this.setState({ prevError: error });
}
}
,因为那不知道我的错误。
我想念什么吗?我只是在错误地处理此问题,是否需要对其进行重新处理(也许将支票移到componentDidUpdate()
内)?
我的意思的完整React示例:
logErrorToMyService
const logErrorToMyService = () => console.warn('I should only be run once');
class ErrorBoundary extends React.Component {
state = {
error: false,
prevError: new Error(),
}
componentDidCatch(error, info) {
this.setState({ error: true });
// none of the below code will work correctly
const isNewError = (error.toString() !== this.state.prevError.toString());
// always true since setState is async
if (isNewError) {
logErrorToMyService(error, info); // should only run once
this.setState({ prevError: error });
}
}
render() {
if (this.state.error) {
return <div>Something went (purposefully) wrong.</div>;
}
return this.props.children;
}
}
// below is 10 purposefully buggy component instances
const BuggyComponent = () => (
<div>{purposefully.throwing.error}</div>
)
const App = () => (
<ErrorBoundary>
{[...Array(10)].map((_, i) => <BuggyComponent key={i} />)}
</ErrorBoundary>
)
ReactDOM.render(
<App />,
document.getElementById('root')
);
更新 :除了将<div id='root'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.1/umd/react-dom.development.js"></script>
切换到类中的字段之外,我还将其更改为数组,以便重复错误-但这可能两者之间的不同错误也将被跳过。
答案 0 :(得分:1)
在您发布的代码中,Foo.Web2/wwwroot/assets
会在第一时间运行componentDidCatch()
回调之前迅速连续触发大约十二次。但是,setstate
不必是prevError
的一部分,因为它与组件的外观无关。
只需将其实现为类变量,即可同步设置。