setInterval定时器在ReactJS的render()中不能正常工作
setInterval timer not working properly in render() of ReactJS
我在React组件中有一个倒计时计时器,它的计数为10秒。如果在这10秒内组件接收到后端数据,计时器将停止。如果没有,它将计数到0,此时页面将刷新,并再次计数,以此类推,直到接收到数据。我的代码如下:
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,然后停止,直到数据最终加载。
我不知道为什么会发生这种情况,但我肯定你的代码有点奇怪。
-
首先,保持你的间隔到
state
是非常奇怪的。相反,将它保留在组件实例中,以便您可以轻松地清除它 -
不设置数据,用间隔检查。您可以在api请求完成时释放interval,并将数据设置为state。
-
组件被解散前总是清除间隔
这就是我的建议。
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)
}
实际上,如果你不使用interval和setTimeout,如果你的state.counter
只存在于检查经过了多少秒,那将会更好。
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)
}
setInterval开销很大。不要用它来做这种工作。
相关文章:
- javascript扫雷器floodfill算法不能正常工作
- 为什么这个代码不能正常工作
- 为什么我的JavaScript在Safari上的严格模式下不能正常工作
- 为什么Turbolinks不能正常工作?Rails应用程序
- 用户名输入如果其他块不能正常工作/Javascript-jQuery-AJAX
- 为什么动态加载的事件在我的代码中不能正常工作
- 为什么竞争不能在离子中显示(隐藏在标题下方)(离子竞争不能正常工作)
- 变量只能在函数中局部工作,不能全局工作-Javascript
- 为什么AngularJS$作用域不能正常工作
- 反向名称的JavaScript函数不能正确工作(例如学习JavaScript-O'Reilly)
- 两个独立工作的javascript函数,但不能一起工作
- Rcharts 和 D3 图不能协同工作
- jquery gallery 不能完全工作
- Caret函数没有'如果插入符号在最后一个位置,就不能正常工作
- 如果else-bind不能正常工作,则淘汰
- 我的ajax加载栏出了什么问题?为什么它不能正常工作
- 为什么不'我的if/else语句不能正常工作
- 为什么我的Javascript代码不能正常工作
- 选中的单选按钮在jQuery模式对话框中不能正常工作
- jquery draggable和resizable在动态生成的元素中不能一起工作