SetInterval is working fine, but clearInterval is not working
See my code, i have parent class Channel and and Child class Body, within body when componentDidMount is called, then i setInterval for function refreshState. In refreshState function i try to clearInterval which is not working
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;
Clearing setInterval in React To stop an interval, you can use the clearInterval() method. ... useEffect(() => { const interval = setInterval(() => { setSeconds(seconds => seconds + 1); }, 1000); return () => clearInterval(interval); }, []); ...
I did make a fiddle to test it, and it turns out clearInterval stops all future execution, even those that have already be queued.
The clearInterval() method clears a timer set with the setInterval() method.
Calling clearInterval() inside setInterval() has no effect But after calling clearInterval(), it will continue to execute.
Another way is to save it directly on 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() {
...
}
});
This requires fewer lines of code but it feels a little less clean. I myself save it on state
as the accepted answer suggests, but I am posting this in case someone more knowledgeable might comment on which method is more idiomatic.
Note also that by using the React Timer mixin you don't have to worry about unmount cleanup - this applies to whether you save the intervalId
in state
or on this
.
In order to keep a handle on the intervalId
, you would need to save it in 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() {
...
}
});
Otherwise, it won't survive the render cycle.
Sometimes you need to run a command in an interval using window.setInterval.
When you navigate away from the component (to simulate unmounting), the interval still runs.
Even worse, when you navigate back to Greeting component, another interval process starts!
How to Fix the Issue You need to save the interval ID when you call the setInterval
class Example extends Component {
intervalID = 0;
componentDidMount() {
this.intervalID = setInterval(this.hello, 1000);
}
...
}
To cancel setInterval, you need to call clearInterval, which require the interval ID returned when you called setInterval.
The best place to do is right before the component unmounts (componentWillUnmount).
class Example extends Component {
intervalID = 0;
componentDidMount() {
this.intervalID = setInterval(this.hello, 1000);
}
componentWillUnmount() {
clearInterval(this.intervalID);
}
}
I got it working by using clearInterval on the internal Id from the object returned.
componentDidMount() {
this.interval = setInterval(this.timer, 1000)
console.log(this.interval) // Timeout {_id: 5, _clearFn: ƒ}
}
componentWillUnmount() {
clearInterval(this.interval._id)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With