Timer/Counter 对于 React 组件 - 在使用 setInterval() 增加值后值保持为 0
Timer/Counter for react component - value remains 0 after increasing it with setInterval()
export default function Timer() {
const [timer, setTimer] = useState(0)
const checkTimer = () => {
console.log(timer);
}
useEffect(() => {
const timer = setInterval(() => {
setTimer(prevCount => prevCount + 1);
}, 1000);
startProgram(); //This starts some other functions
return () => {
checkTimer();
clearInterval(timer);
}
}, [])
}
以上是我的代码和主要问题的简化版本 - 我试图通过在 useEffect() 中设置间隔(仅一次)来增加 timer
状态。但是,在 checkTimer()
中,即使控制台语句每秒执行一次,该值始终为 0。我是 reactjs 的新手,希望得到一些帮助,因为这已经花了我太多时间来修复。
checkTimer
向您显示 timer
状态的初始值,因为 过时的关闭 。这意味着在执行 useEffect
时(即 一旦在组件安装时由于 []
作为依赖项 ),它注册了一个 cleanup 函数围绕 checkTimer
函数创建了一个闭包(以及它使用的所有内容,状态或道具值)。当创建此闭包时,timer
状态的值为 0
。它将永远如此。
修复它的选项很少。
一个快速解决方案是使用useRef
:
const timer = useRef(0);
const checkTimer = () => {
console.log(timer.current);
};
useEffect(() => {
const id = setInterval(() => {
timer.current++;
}, 1000);
return () => {
checkTimer();
clearInterval(id);
};
}, []);
检查 以查看解决此问题的更多代码示例。
编辑:
而且,如果您还想在 UI 处显示 timer
,我们需要使用 state,因为我们知道“ref”数据不会在 UI 更新。所以,选项2是使用setTimer
的“updater”形式来读取checkTimer
函数中的最新状态数据:
const [timer, setTimer] = useState(0);
const checkTimer = () => {
let prevTimer = 0;
setTimer((prev) => {
prevTimer = prev; // HERE
return prev; // Returning same value won't change state data and won't causes a re-render
});
console.log(prevTimer);
};
useEffect(() => {
const id = setInterval(() => {
setTimer((prev) => prev + 1);
}, 1000);
return () => {
checkTimer();
clearInterval(id);
};
}, []);
export default function Timer() {
const [timer, setTimer] = useState(0)
const checkTimer = () => {
console.log(timer);
}
useEffect(() => {
const timer = setInterval(() => {
setTimer(prevCount => prevCount + 1);
}, 1000);
startProgram(); //This starts some other functions
return () => {
checkTimer();
clearInterval(timer);
}
}, [])
}
以上是我的代码和主要问题的简化版本 - 我试图通过在 useEffect() 中设置间隔(仅一次)来增加 timer
状态。但是,在 checkTimer()
中,即使控制台语句每秒执行一次,该值始终为 0。我是 reactjs 的新手,希望得到一些帮助,因为这已经花了我太多时间来修复。
checkTimer
向您显示 timer
状态的初始值,因为 过时的关闭 。这意味着在执行 useEffect
时(即 一旦在组件安装时由于 []
作为依赖项 ),它注册了一个 cleanup 函数围绕 checkTimer
函数创建了一个闭包(以及它使用的所有内容,状态或道具值)。当创建此闭包时,timer
状态的值为 0
。它将永远如此。
修复它的选项很少。
一个快速解决方案是使用useRef
:
const timer = useRef(0);
const checkTimer = () => {
console.log(timer.current);
};
useEffect(() => {
const id = setInterval(() => {
timer.current++;
}, 1000);
return () => {
checkTimer();
clearInterval(id);
};
}, []);
检查
编辑:
而且,如果您还想在 UI 处显示 timer
,我们需要使用 state,因为我们知道“ref”数据不会在 UI 更新。所以,选项2是使用setTimer
的“updater”形式来读取checkTimer
函数中的最新状态数据:
const [timer, setTimer] = useState(0);
const checkTimer = () => {
let prevTimer = 0;
setTimer((prev) => {
prevTimer = prev; // HERE
return prev; // Returning same value won't change state data and won't causes a re-render
});
console.log(prevTimer);
};
useEffect(() => {
const id = setInterval(() => {
setTimer((prev) => prev + 1);
}, 1000);
return () => {
checkTimer();
clearInterval(id);
};
}, []);