Javascript setInterval计时器在ReactJS的render()中工作不正常
我在React组件中有一个倒计时计时器,它会计时10秒。如果在这10秒内组件接收到后端数据,计时器将停止。否则,它将倒计时到0,此时页面将刷新,然后再次倒计时,以此类推,直到收到数据为止。我的代码如下:Javascript setInterval计时器在ReactJS的render()中工作不正常,javascript,jquery,reactjs,timer,Javascript,Jquery,Reactjs,Timer,我在React组件中有一个倒计时计时器,它会计时10秒。如果在这10秒内组件接收到后端数据,计时器将停止。否则,它将倒计时到0,此时页面将刷新,然后再次倒计时,以此类推,直到收到数据为止。我的代码如下: constructor() { ... this.counter = 10; ... } render() { const interval = setInterval(() => { const result = this.state.d
constructor() {
...
this.counter = 10;
...
}
render() {
const interval = setInterval(() => {
const result = this.state.data;
if (result) {
this.setState({
resultsReceived: true
});
clearInterval(interval);
} else {
this.setState({
resultsReceived: false
});
this.counter = this.counter - 1;
if (this.counter === 0) {
window.location.reload();
}
}
}, 1000);
问题是,计时器似乎不是每秒递减一次。相反,该行为是不稳定的-从10到7,速度非常快,然后可能会挂起,甚至在0后继续,即负。页面正在重新加载。此代码是错误的,还是与React的状态相关的问题?任何帮助都会很好
更新:
我将代码更改为:
constructor() {
this.state = {
...
interval: '',
counter: 10
};
}
componentWillMount() {
$.ajax({
url: this.props.api,
datatype: 'json',
cache: false,
success: (data) => {
this.setState({ data });
}
});
const interval = setInterval(() => {
const results = this.state.data;
if (results) {
this.setState({
resultsReceived: true
});
clearInterval(this.state.interval);
} else {
this.setState({
resultsReceived: false
});
let counter;
counter = this.state.counter - 1;
this.setState({ counter });
if (this.state.counter === 0) {
window.location.reload();
}
}
}, 1000);
this.setState({ interval });
}
componentWillUnmount() {
clearInterval(this.state.interval);
}
它比以前更好,因为计时器在第一次正常工作-它每1秒从10变为0。但是,即使在10秒之后,数据仍未加载,并且计时器再次从10开始,它达到9,然后停止,直到数据最终加载。页面也变得非常慢。我不知道为什么会发生这种情况,但我确信您的代码有点奇怪
状态是非常奇怪的。相反,请将其保存在组件实例中,以便轻松清除
constructor() {
...
this.interval = null
this.state = { counter: 10 }
...
}
componentWillMount() {
$.ajax({
url: this.props.api,
datatype: 'json',
cache: false,
success: (data) => {
this.setState({ data })
clearInterval(this.interval);
},
});
this.interval = setInterval(() => {
if (counter <= 0) {
clearInterval(this.interval);
location.reload();
return;
}
this.setState({
counter: this.state.counter - 1,
});
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval)
}
时间间隔很贵。不要将其用于此类工作。我建议您阅读本文。您正在寻找componentWillMount和componentWillMount。是否将代码放入render()函数以确保不会启动大量新的间隔计时器?我不熟悉reactjs,但通常每秒调用render()多次。@AntonBanchev。我正在尝试在componentWillMount和componentWillMount中使用它们,正如Jesús Quintana所说的谢谢!成功了。实际上,我使用了你的第一个解决方案,因为我需要显示计数器值,因为它每秒钟递减一次。但我也理解你的第二个解决方案。我以前没有将setInterval与React一起使用过,因此从您的解决方案中学习
constructor() {
...
this.timeout = null
...
}
componentWillMount() {
$.ajax({
url: this.props.api,
datatype: 'json',
cache: false,
success: (data) => {
this.setState({ data })
clearTimeout(this.timeout);
}
});
this.timeout = setTimeout(() => {
clearTimeout(this.timeout);
location.reload();
}, 1000 * 10);
}
componentWillUnmount() {
clearTimeout(this.timeout)
}