首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何避免componentDidCatch()多次触发某些东西?

如何避免componentDidCatch()多次触发某些东西?
EN

Stack Overflow用户
提问于 2018-08-27 23:11:52
回答 1查看 533关注 0票数 0

如果一个组件渲染了10次,并且有一个错误,componentDidCatch()将触发10次,并返回相同的错误。目前,我在catch上发出一个API请求来记录错误,但我只希望该错误被记录一次。

我的第一个想法是在状态中保存我自己的prevError,并检查传递给componentDidCatch()error是否相同。但这不会起作用,因为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(),因为它不知道我的错误。

我是不是遗漏了什么?我只是错误地处理了这个问题,需要重新处理它(也许将检查转移到logErrorToMyService中)?

完整的React示例说明了我的意思:

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>

更新:除了将prevError切换为类上的字段外,我还将其更改为数组,以便也跳过重复的错误-但两者之间可能存在不同的错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-28 07:19:55

在您发布的代码中,在setstate回调函数第一次运行之前很久,componentDidCatch()将快速连续地触发十几次。然而,prevError不一定是state的一部分,因为它对组件的外观没有影响。

只需将其实现为类变量,以便同步设置。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52042251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档