REACT搭载元器件的setInterval不清除间隔因“状态更新”

时间:2019-01-31 08:53:16

标签: javascript reactjs

我有一个间隔计时器,设定一函数,今天套的日期进入状态,我在初始化componenteDidMount。尽管我清除了componentWillUnmount中的间隔,但是在快速切换组件之间仍然会出现错误(这就是我捕获错误的方式)。

这是错误:

警告: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

我试图操纵从虚假的私人_isMounted变量设置为true整个周期,迫使一个条件检查在我的setTodaysDate()之前设置状态,但即使没有解决不了的问题。< / p>

  // _isMounted = false;  <----- tried this method to no avail

  state = {
    selectedDate: ""
  };

  componentDidMount() {
    this.setTodaysDate();
    this.interval = setInterval(() => this.setTodaysDate(), 40 * 1000 * 360);
    // this._isMounted = true;  <----- tried
  }


  componentWillUnmount() {
    clearInterval(this.interval);
    // this._isMounted = false;  <----- tried
  }


  setTodaysDate = () => {
    // if (this._isMounted) {  <----- tried
    this.setState({
      selectedDate: moment(moment(), "YYYY-MM-DDTHH:mm:ss")
        .add(1, "days")
        .format("YYYY-MM-DD")
    });

    // }  <----- tried

  }

我在一个头绪否则为“堵塞泄漏。”

修改原来,由于加布里埃莱下面,真正的原因是我使用的是lodash去抖动方法(其中,我还的setState),我的卸载期间从未取消,从而导致“泄漏“:

  debounceCloseAlert = _.debounce(() => {
    this.setState({ alertVisible: false });
  }, 5000);

2 个答案:

答案 0 :(得分:4)

查看您的组件,我认为问题不在于您的setInterval。处理它的方法是正确的方法,不应产生上述错误。

我认为问题在于在您的debounceCloseAlert方法中使用_.debounce。还会创建一个超时,您不会在任何地方清除该超时。

_.debounce返回的值包括一个.cancel()方法来清除间隔。因此,只需在您的this.debounceCloseAlert.cancel();中调用componentWillUnmount,它将清除它。

答案 1 :(得分:2)

您是否尝试过将间隔引用保存为组件状态?

  state = {
    selectedDate: "",
    interval: null
  };

  componentDidMount() {
    this.setTodaysDate();
    const interval = setInterval(() => this.setTodaysDate(), 40 * 1000 * 360);
    this.setState({interval});
  }


  componentWillUnmount() {
    clearInterval(this.state.interval);
  }


  setTodaysDate = () => {
    this.setState({
      selectedDate: moment(moment(), "YYYY-MM-DDTHH:mm:ss")
        .add(1, "days")
        .format("YYYY-MM-DD")
    });


  }

有些人似乎还通过使用interval._id获得了运气。

(使用您的初始代码)

componentWillUnmount() {
  clearInterval(this.interval._id)
}