reactjs - setInterval 和 React 钩子会产生意想不到的结果
问题描述
我在使用 create-react 搭建的应用程序中定义了以下组件:
import React, { useState } from 'react';
const Play = props => {
const [currentSecond, setCurrentSecond] = useState(1);
let timer;
const setTimer = () => {
timer = setInterval(() => {
if (currentSecond < props.secondsPerRep) {
setCurrentSecond(() => currentSecond + 1);
}
}, 1000);
}
setTimer();
return (
<div>
<div>
<p>{currentSecond}</p>
</div>
</div>
);
}
export default Play;
并且currentSecond
每秒更新一次,直到它遇到props.secondsPerRep
但是如果我尝试setInterval
从点击处理程序启动:
import React, { useState } from 'react';
const Play = props => {
const [currentSecond, setCurrentSecond] = useState(1);
let timer;
const setTimer = () => {
timer = setInterval(() => {
if (currentSecond < props.secondsPerRep) {
setCurrentSecond(() => currentSecond + 1);
}
}, 1000);
}
return (
<div>
<div>
<button onClick={setTimer}>Start</button>
<p>{currentSecond}</p>
</div>
</div>
);
}
export default Play;
然后currentSecond
在setInterval
回调内总是返回初始值,即1。
任何帮助都非常感谢!
解决方案
您的问题是这条线setCurrentSecond(() => currentSecond + 1);
,因为您只调用setTimer
一次,您的间隔将始终在初始状态currentSecond
为 1 时关闭。
幸运的是,您可以通过传递给setCurrentSecond
like的函数中的 args 访问实际的当前状态来轻松解决这个问题setCurrentSecond(actualCurrentSecond => actualCurrentSecond + 1)
此外,您要非常小心地在功能组件主体中任意定义间隔,因为它们不会被正确清除,就像如果您再次单击按钮,它将开始另一个间隔而不清除前一个间隔.
我建议您查看这篇博文,因为它会回答您对间隔 + 挂钩的任何问题:https ://overreacted.io/making-setinterval-declarative-with-react-hooks/
推荐阅读
- node.js - Azure 静态 Web 应用 NodeJS 环境变量
- python - 400 错误请求,PUT 创建 URL,Api Copyleaks
- macos - 接收 zsh:操作系统更新后通过终端(Big Sur/M1)运行任何命令后被杀死
- python - IF AND Excel 公式转换为 SQL 或 Python
- sympy - 如何将四元数转换为人类可读的乳胶
- r - 具有公式的函数的正确 dplyr 函数式编程语法是什么
- python - Python:如何加载 CSV 文件并从中提取特定列以用作数据输入?
- javascript - 在反应应用程序中包含脚本会大大降低灯塔性能得分
- java - 房间数据库迁移:java.lang.IllegalStateException:迁移没有正确处理
- reactjs - React+Typescript 条件渲染