clearInterval 在 reactjs 中不起作用

IT技术 reactjs
2021-04-26 03:41:24

SetInterval 工作正常,但 clearInterval 不起作用

看我的代码,当componentDidMount被调用时,我有父类Channel和子类Body,在body内,然后我为函数refreshState设置Interval。在 refreshState 函数中,我尝试清除无效的间隔

var Header = require('../../common/header.jsx');
var Sidebar = require('../../common/sidebar.jsx');
var Footer = require('../../common/footer.jsx');

var Body = React.createClass({

  componentDidMount: function() {
    this.intervalId  = setInterval(this.refreshStats, 1000);
  },

  componentWillUnmount: function(){
    clearInterval(this.intervalId);
  },

  refreshStats: function() {
        console.log(this.intervalId);
        clearInterval(this.intervalId);
  },

  render: function() {
    return (
      <Container id='body'>
        <Grid>
          <Row>
            <Col sm={12}>
              <PanelContainer>
                <Panel>
                  <PanelBody>
                    Test
                  </PanelBody>
                </Panel>
              </PanelContainer>
            </Col>
          </Row>
        </Grid>
      </Container>
    );
  }
});

var Channel = React.createClass({
  mixins: [SidebarMixin, State],
  render: function() {
    var classes = React.addons.classSet({
      'container-open': this.state.open
    });
    return (
      <Container id='container' className={classes}>
        <Sidebar />
        <Header />
        <Body />
        <Footer />
      </Container>
    );
  }
});

module.exports = Channel;
4个回答

另一种方法是直接将其保存在this

var Body = React.createClass({

componentDidMount: function() {
    this.intervalId  = setInterval(this.refreshStats, 1000);
},

componentWillUnmount: function(){
   clearInterval(this.intervalId);
},

refreshStats: function() {
    console.log(this.intervalId);
    clearInterval(this.intervalId);
},

render: function() {
    ...
}
});

这需要更少的代码行,但感觉不太干净。我自己state按照已接受的答案所建议的那样保存它,但我将其发布,以防有​​知识渊博的人评论哪种方法更惯用。

另请注意,通过使用React Timer mixin,您不必担心卸载清理 - 这适用于您是否保存intervalIdinstate或 on this

为了保持手柄intervalId,你需要将它保存在state

var Body = React.createClass({

  getInitialState = function() {
    return {};
  },

  componentDidMount: function() {
    intervalId  = setInterval(this.refreshStats, 1000);
    this.setState({intervalId: intervalId});
  },

  componentWillUnmount: function(){
    clearInterval(this.state.intervalId);
  },

  refreshStats: function() {
    console.log(this.state.intervalId);
    clearInterval(this.state.intervalId);
  },

  render: function() {
    ...
  }
});

否则,它将无法在渲染周期中存活下来

有时您需要使用 window.setInterval 在一个时间间隔内运行命令。

当您离开组件(以模拟卸载)时,该时间间隔仍会运行。

更糟糕的是,当您导航回 Greeting 组件时,另一个间隔过程开始了!

如何解决此问题您需要在调用 setInterval 时保存间隔 ID

class Example extends Component {
  intervalID = 0;

  componentDidMount() {
    this.intervalID = setInterval(this.hello, 1000);
  }
  ...
}

取消setInterval需要调用clearInterval,它需要调用setInterval时返回的间隔ID。

最好的地方是在组件卸载之前 (componentWillUnmount)。

class Example extends Component {
  intervalID = 0;

  componentDidMount() {
    this.intervalID = setInterval(this.hello, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.intervalID);
  }
}

我通过在返回的对象的内部 Id 上使用 clearInterval 使其工作。

componentDidMount() {
  this.interval = setInterval(this.timer, 1000)
  console.log(this.interval) // Timeout {_id: 5, _clearFn: ƒ}
}

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