问题
So, we have this simple React component that receives an integer from the father component. When the button is clicked, we display the integer on the screen and the countdown begins.
The question is how can I stop the countdown. While reading other SO posts, I found about clearInterval(), but it seems I am missing something here.
Any help would be greatly appreciated. Bonus appreciation points will be awarded if someone is kind enough to explain to me why the sample code is not working as expected.
import React from "react";
export default class TestInterval extends React.Component {
constructor(props) {
super(props);
this.state = {
countDown: this.props.countDown, // An integer from father component
}
}
timer = () => {
setInterval(() => {
if (this.state.countDown === 0) {
this.stopCountDown();
}
this.setState( prevState => ({
countDown: prevState.countDown - 1,
}));
}, 1000)
}
startCountDown = () => {
this.timer();
}
stopCountDown = () => {
clearInterval(this.timer); // Not working
}
render () {
return (
<div>
<button onClick={this.startCountDown}>
Start Countdown
</button>
<p>{this.state.countDown}</p>
</div>
);
}
}
回答1:
You need to store the interval reference returned from setInterval
.
From the docs:
It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
So your code should look like that for example:
this.interval = setInterval(() => {...
and then clear it:
clearInterval(this.interval);
I would check the condition after the state has truly set (setState
is asynchronous) you can do it inside the callback of setState
.
this.interval = setInterval(() => {
this.setState(prevState => ({
countDown: prevState.countDown - 1,
}), () => {
if (this.state.countDown === 0) {
this.stopCountDown();
}
});
}, 1000)
Running example:
class TestInterval extends React.Component {
constructor(props) {
super(props);
this.state = {
countDown: this.props.countDown, // An integer from father component
}
}
timer = () => {
this.interval = setInterval(() => {
this.setState(prevState => ({
countDown: prevState.countDown - 1,
}), () => {
if (this.state.countDown === 0) {
this.stopCountDown();
}
});
}, 1000)
}
startCountDown = () => {
this.timer();
}
stopCountDown = () => {
clearInterval(this.interval); // Not working
}
render() {
return (
<div>
<button onClick={this.startCountDown}>
Start Countdown
</button>
<p>{this.state.countDown}</p>
</div>
);
}
}
ReactDOM.render(<TestInterval countDown={3} />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
来源:https://stackoverflow.com/questions/47254124/clear-interval-in-react-class