当我的React应用程序中的路线发生变化时,我clearInterval()和应用程序中断

uee*_*iie 3 javascript setinterval reactjs react-router-dom

我正在使用React-router-dom开发一个React应用程序

我有一个带有一些react-router-dom的菜单<NavLink />,每个菜单都将我带到不同的路线。

在我的主要路线中,path="/"我的chartComponent具有一个图表,该图表会随着随机数据而不断变化,如下所示:this.chartChangeId = setInterval(()=> this.setState(data), 1500)

在我添加以下内容之前:

componentWillUnmount(){
    clearInterval(this.chartChangeId);
}
Run Code Online (Sandbox Code Playgroud)

chartComponent我的应用程序没有中断,但是出现了以下错误:

警告:只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState,replaceState或forceUpdate。这是无人值守。请检查BrainWaveChart组件的代码。

所以我将其添加到生命周期中。

但是现在,当我单击其中一个<NavLink />转到另一条路线时,我的应用程序中断了,并且出现此错误:

未捕获到的TypeError错误:timeout.close不是在BrainWaveChart.componentWillUnmount(brainwaveChart.jsx:116x)处的export.clearTimeout.exports.clearInterval(main.js:14)处,在HTMLUnknownElement.call处的callComponentWillUnmountWithTimer(vendor_f02cab182c1842c98837.js:45235)处的export.clearTimeout.exports.clearInterval(main.js:14) vendor_f02cab182c1842c98837.js:37015)在Object.invokeGuardedCallbackDev(vendor_f02cab182c1842c98837.js:37054)在invokeGuardedCallback(vendor_f02cab182c1842c98837.js:36911)在safelyCallComponentWillUnmount(vendor_f02cab182c1842c98837.js:45242)在commitUnmount(vendor_f02cab182c1842c98837.js:45368)在commitNestedUnmounts(vendor_f02cab182c1842c98837.js :45404)在unmountHostComponents(vendor_f02cab182c1842c98837.js:45687)

我做错了吗?

Edu*_*cko 5

()=> this.setState(data)即使您清除间隔也仍在执行,因为间隔已在内存中且位于异步堆栈中。您需要做的是检查组件是否存在,然后再更新状态。最简单的方法是

const {clearInterval, setInterval} = window;
class Comp extends React.Component {
  constructor(props) {
    super(props);
    this.mounted = false;
    this.interval = setInterval(() => {
      if(this.mounted) this.setState();
    })
  }
  componentWillMount() {
    this.mounted = true;
  }
  componentWillUnmount() {
    this.mounted = false;
    clearInterval(this.interval);
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,这更像是反菜式。正确的方法是根本不使用Ajax中的setState。https://reactjs.org/blog/2015/12/16/ismount-antipattern.html