我正在尝试用一些简单的项目学习React,但似乎无法理解下面的代码,因此希望您能解释一下。
这段代码来自一个简单的倒计时函数,工作得很好;但是,当我console.log时,setTime似乎正确地更新了'seconds'的值,但是当我console.log(time)之后立即给我3的原始值。为什么会这样?
附加问题-当函数startCountdown被调用时,在我的JSX中出现的正确时间值中有延迟,我认为这是由于变量"秒"被填充和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)
};
更新:在函数中没有看到正确值的原因是setState发生的方式(setTime)。当你调用setState时,它会批量调用并在后台中执行它们。。因此,你不能在调用setState后立即期望能够在函数内部使用它的值。
你可以将console.log从函数中取出,并将其放入渲染方法中,你将看到正确的值。
或者你可以试着这样使用useEffect
//这意味着当你使用setTime并且组件更新时,打印当前的time值。只有当时间改变时才这样做。
useEffect(()=>{
console.log(time);
},[time]);
每次你setState时,你都在重新渲染组件,这导致了state的混乱。在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;