javascript - 如何让 setState 在 setInterval 中工作?(目前正在工作)
问题描述
function func(){
const [time, setTime] = useState(10);
var timeRemaining = 10;
const myInterval = setInterval(() => {
if (timeRemaining > 0) {
timeRemaining = timeRemaining - 1;
setTime(timeRemaining);
} else { clearInterval(myInterval) }
}, 1000);
return <div>{time}</div>
}
上面的代码由于变量timeRemaining
. 但是,如果我删除该变量,它就会停止工作(为了保持代码干净):
const myInterval = setInterval(() => {
if (time> 0) { setTime(time-1); }
else { clearInterval(myInterval); }
}, 1000);
通过以上述方式重写它,它会停止更新time
.
解决方案
使用 effects 来控制间隔,使用 ref 来保存对间隔计时器引用的引用,并使用功能状态更新来正确管理状态。
- 效果 1 - 间隔效果的设置(挂载)和清理(卸载)
- 效果 2 - 当时间到达 0 时清除间隔
功能组件代码:
function App() {
const timerRef = useRef(null);
const [time, setTime] = useState(10);
useEffect(() => {
// Use pure functional state update to correctly queue up state updates
// from previous state time value.
// Store returned interval ref.
timerRef.current = setInterval(() => setTime(t => t - 1), 1000);
// Return effect cleanup function
return () => clearInterval(timerRef.current);
}, []); // <-- Empty dependency array, effect runs once on mount.
useEffect(() => {
// Clear interval and nullify timer ref when time reaches 0
if (time === 0) {
clearInterval(timerRef.current);
timerRef.current = null;
}
}, [time]); // <-- Effect runs on mount and when time value updates.
return <div>{time}</div>;
}
推荐阅读
- angular - 每次加载组件时,Angular 4 路由都会调用 ngOnInit,重复 API 调用
- php - 用ffmpeg重新创建图像安全吗?
- python - Python for maya:为什么我不能将变量与通配符结合使用?
- java - 从同一个表中收集列值的 Hibernate 映射
- javascript - 尝试从导出的函数返回 RxJS 可观察流
- windows - Installshield问题设置文件权限
- sql-server - 将 Asp.net 核心 web api 部署到 IIS,但其他计算机使用 IP:{port}/api/{controller} 无法访问
- swift - UITextField 委托 textFieldShouldReturn 未通过硬件键盘返回调用
- amazon-web-services - 如何向安装在 EC2 上的烧瓶发送 http 请求
- tensorflow-model-analysis - 如何使用 jupyterlab notebook 解决 tensorflow-model-analysis 的安装问题?