请考虑以下组件:
import React from 'react';
export default class HeartBeat extends React.Component {
constructor(props) {
super(props);
this.state = {
timeRemaining: 15 * 60,
timeBeforeWarning: (15 * 60) - 300,
showWarning: false,
showError: false,
};
this.currentTick = 0;
this.intervalId = null;
}
componentDidMount() {
this.intervalId = setInterval(this.updateTick.bind(this), 6000)
}
updateTick() {
if (this.currentTick < 600) {
this.currentTick += 60;
} else if (this.currentTick > 540 && this.currentTick < 900) {
if (!this.state.showWarning) {
this.setState({
showWarning: true,
});
}
this.currentTick += 60;
} else if (this.currentTick === 900) {
this.setState({
showWarning: false,
showError: true,
});
clearInterval(this.intervalId);
}
console.log(this.currentTick);
}
resetTimmer() {
this.intervalId = 0;
this.setState({
showWarning: false,
});
}
render() {
if (this.state.showWarning) {
return (
<div className="alert alert-warning">Your session is about to expire in 5 minutes <a href="#" onClick={this.resetTimmer.bind(this)}>Click me to stay logged in</a></div>
)
}
if (this.state.showError) {
return (
<div className="alert alert-danger">Your session expired.</div>
)
}
return null;
}
}
这里的想法很简单:每6秒钟将currentTick
增加60。如果该值大于540但小于900,则显示警告。如果其为900,则显示错误。如果他们单击警告中的链接,则应该重置计时器,我们应该重新开始。
this.intervalId = 0
,此方法不起作用。因为它只是不断增加现有值。我确实尝试过clearInterval(this.intervalId)
,但这完全停止了计时器。我只想重置计时器。
currentTick
为660时显示,这不是应该发生的情况。不知道如何解决这个问题。当警告显示时,我们对服务器进行ajax调用,实际上只是对其进行ping操作以保持会话有效(我使用Laravel作为后端)。成功返回200后,我们将重置计时器。 (我知道如何执行ajax调用,就目前而言,我已经将其作为简单的事件处理程序来“重置计时器”)
注意:出于测试目的,我将计时器设置为setInterval(this.updateTick.bind(this), 6000)
而不是60000
。据我所知,它将设置为60000。
有人可以告诉我如何重置计时器,以便重新启动计时器吗?如果我将计时器的逻辑放置在正确的位置?
答案 0 :(得分:3)
这是一个基本间隔,每分钟更新一次状态:
import React from 'react'
class Counter extends React.Component{
state = {
timer: 0
}
tick = null
onTick = () => this.setState({timer : this.state.timer + 60})
componentDidMount(){
this.tick = setInterval(this.onTick, 60000)
}
componentWillUnmount(){
clearInterval(this.tick)
}
render(){
const { timer} = this.state
return(
<div>
{(timer > 540 && timer <900) && 'Warning'}
{timer > 900 && 'Error'}
</div>
)
}
}
答案 1 :(得分:0)
我把这个问题作为学习setInterval
如何与钩子一起工作的机会。在遇到Dan Abramov的这篇文章之前,我一直遇到一些问题:
https://overreacted.io/making-setinterval-declarative-with-react-hooks/
然后,我使用帖子中建议的useInterval
函数在CodeSandbox上创建了该问题的版本。
https://codesandbox.io/s/ticker-liqo9
我希望对您有帮助