我想设置一个超时,从现在开始关闭 X 秒数。如果 X 发生变化,我想清除超时并根据 X 的新值开始新的超时。当我尝试清除超时时,它不起作用。这是我的代码
componentWillReceiveProps(nextProps) {
if (this.props.expirationTimeout !== nextProps.expirationTimeout) {
this.setState({
expirationTimeout: nextProps.expirationTimeout
});
window.clearTimeout(this.setExpiration);
this.setExpiration(nextProps.expirationTimeout);
}
}
setExpiration(time) {
let timeouts = [];
for (var i = 0; i < timeouts.length; i++) {
clearTimeout(timeouts[i]);
}
var t = time - new Date().getTime();
timeouts.push(setTimeout(this.state.logoutUserAndRedirect, t));
}
- 要使用
clearTimeout()
您需要之前返回setTimeout
id 的 id - 当前具有计时器 ID 的
setTimeout
的结果被存储到块级变量timeouts
中。所以没有机会在componentWillReceiveProps
中将其用于clearTimeout
. - 由于对状态的每次更改都会触发重新渲染,因此我建议不要将
props.expirationTimeout
值存储到状态中。logoutUserAndRedirect
也是如此.把它放在state
是没有意义的. - 如果计时器的新值小于以前的值怎么办? 如果根据新值,您已经错过了执行计划的时间怎么办? 如果延迟值<0,
setTimeout
将以这种方式工作。不是很好吗?:) [UPD] 我还认为需要存储最近超时开始时的时间戳。这样,我们将能够在延迟值更改后对其进行更正。
componentWillReceiveProps(nextProps) { if (this.props.expirationTimeout !== nextProps.expirationTimeout) { this.modifyExpiration(this.timerStartedAt + nextProps.expirationTimeout - this.props.expiration); } } modifyExpiration(time) { this.timeoutId && clearTimeout(this.timeoutId); this.timeoutId = setTimeout(this.logoutUserAndRedirect, time); this.timerStartedAt = +new Date(); }