我有一个状态变量resendTime
和magicLinkState
。
我想在magicLinkState发送后的10秒钟内从setResendTime
切换到resendTime - 1
。
我已经尝试了下面的代码,但这并不更新resendTime每一秒。
useEffect(() => {
if (magicLinkState === "sent" && resendTime > 0) {
const timer = setInterval(() => setResendTime(resendTime - 1), 1000);
console.log(resendTime);
return () => clearInterval(timer);
}
}, []);
这段代码只更新第一秒的状态。我也尝试过传递依赖关系数组,但没有成功。我如何让它更新状态,以便我达到预期的效果。
3条答案
按热度按时间rdlzhqv91#
代码中的基本思想是正确的,但需要进行一些调整。
1.需要将
magicLinkState
添加到效果的依赖项中,否则在获取sent
值时它不会触发,但只有在最初设置为该值时才会触发。1.应该使用箭头语法:
setResendTime((prevResendTime) => prevResendTime - 1)
,以便每次获取正确的状态值1.在这个效果中不需要清除函数,因为你只想在它被触发并且减少10次到
resendTime
之后清除间隔。1.您应该添加一些局部
count
变量,以便仅减少10次,而不是永远减少在这些更改之后,您的代码应该如下所示:
您可以在CodeSandbox中找到演示此解决方案的示例。
这里还有更多的改进要做,但它们是基于您的需要。例如,如果
magicLinkState
更改为“已发送”,然后更改为其他内容,然后在10秒内返回到“已发送”,2个间隔将运行并以双倍的速度减少。tcomlyy62#
您只是遇到了初始
resendTime
状态值上的过时闭包问题。通过使用函数状态更新来正确访问以前的状态值(而不是周围回调作用域中关闭的任何值),可以很容易地解决这个问题。还要注意的是,由于闭包的原因,如果你想记录
resendTime
状态 as 它的更新,你需要使用另一个useEffect
钩子,它有一个适当的依赖关系。这也是你需要移动逻辑来检查时间间隔是否完成的地方。使用React ref来存储对定时器id的引用。cwdobuhd3#
我可以用时间戳代替时间间隔吗?这个函数调用一次后会检查10秒内的每一秒