我正在尝试通过一些简单的项目来学习 React,但似乎无法理解以下代码,因此希望得到解释。
这个来自简单倒计时函数的片段运行良好;但是,当我 console.log 时,setTime 似乎正确更新了 'seconds' 的值,但是当我在 console.log(time) 之后立即给我原始值 3 时。这是为什么?
额外问题 - 当函数 startCountdown 被调用时,我的 JSX 中出现的正确时间值会出现延迟,我认为这归因于变量“seconds”被填充和 setInterval 函数的开始,所以我不倒计时没有顺利和准确的开始。有没有办法解决这个问题?
const [ time, setTime ] = useState(3);
const [ clockActive, setClockActive ] = useState(false);
function startCountdown() {
let seconds = time * 60;
setClockActive(true);
let interval = setInterval(() => {
setTime(seconds--);
console.log(seconds); // Returns 179
console.log(time); // Returns 3
if(seconds < 0 ) {
clearInterval(interval);
}
}, 1000)
};
答案 0 :(得分:0)
更新: 您在函数中没有看到正确值的原因是 setState 发生的方式(setTime)。当您调用 setState 时,它会批量调用并在后台需要时执行它们。所以你不能调用 setState 然后立即期望能够在函数内部使用它的值。
你可以把console.log从函数中取出,放到render方法中,你会看到正确的值。
或者你可以像这样试试useEffect。
//这意味着无论何时使用 setTime 并且组件更新,打印时间的当前值。仅在时间变化时执行此操作。
useEffect(()=>{
console.log(time);
},[time]);
每次 setState 时,您都在重新渲染组件,这会导致对状态的破坏。因此,在 setInterval 中的每一秒,您都在重新渲染组件并在您已经运行的组件之上重新启动它。要解决此问题,您需要使用 useEffect 并传入您正在使用的状态变量。我在这里为你做了一个例子:
https://codesandbox.io/s/jolly-keller-qfwmx?file=/src/clock.js
import React, { useState, useEffect } from "react";
const Clock = (props) => {
const [time, setTime] = useState(3);
const [clockActive, setClockActive] = useState(false);
useEffect(() => {
let seconds = 60;
setClockActive(true);
const interval = setInterval(() => {
setTime((time) => time - 1);
}, 1000);
if (time <= 0) {
setClockActive(false);
clearInterval(interval);
}
return () => {
setClockActive(false);
clearInterval(interval);
};
}, [time, clockActive]);
return (
<>
{`Clock is currently ${clockActive === true ? "Active" : "Not Active"}`}
<br />
{`Time is ${time}`}
</>
);
};
export default Clock;