我正在尝试自己实现倒计时器,只是为了更好地了解Hook。我知道有一些库可以使用,但不想使用它们。我的代码中的问题是,在“timer”函数中无法获取在启动计时器函数中更新的更新状态。我正在尝试实现具有触发启动、停止、恢复和手动触发功能的计时器,其他组件可以使用倒计时组件。
import React, { useState } from 'react';
const Countdown = ({ countDownTimerOpt }) => {
const [getObj, setObj] = useState({
formatTimer: null,
countDownTimer: 0,
intervalObj: null,
});
const { formatTimer, countDownTimer, intervalObj } = getObj;
if (countDownTimerOpt > 0 && intervalObj === null) {
startTimer();
}
function startTimer() {
const x = setInterval(() => {
timer();
}, 1000);
setObj((prev) => ({
...prev,
countDownTimer: countDownTimerOpt,
intervalObj: x,
}));
}
function timer() {
var days = Math.floor(countDownTimer / 24 / 60 / 60);
var hoursLeft = Math.floor(countDownTimer - days * 86400);
var hours = Math.floor(hoursLeft / 3600);
var minutesLeft = Math.floor(hoursLeft - hours * 3600);
var minutes = Math.floor(minutesLeft / 60);
var remainingSeconds = countDownTimer % 60;
const formatTimer1 =
pad(days) +
':' +
pad(hours) +
':' +
pad(minutes) +
':' +
pad(remainingSeconds);
if (countDownTimer === 0) {
clearInterval(intervalObj);
} else {
setObj((prev) => ({
...prev,
formatTimer: formatTimer1,
countDownTimer: prev['countDownTimer'] - 1,
}));
}
}
function pad(n) {
return n < 10 ? '0' + n : n;
}
return <div>{formatTimer ? formatTimer : Math.random()}</div>;
};
export default Countdown;
import React, { useState, useEffect } from 'react';
import Timer from '../../components/countdown-timer/countdown.component';
const Training = () => {
const [getValue, setValue] = useState(0);
useEffect(() => {
const x = setTimeout(() => {
console.log('setTimeout');
setValue(10000);
}, 5000);
return () => clearInterval(x);
}, []);
return <Timer countDownTimerOpt={getValue} />;
我不想在训练页面内使用任何设置间隔,因为倒计时组件还会在考试页面中使用。
setInterval
在第一次渲染时被调用,而timer
是在组件内部创建的。因此,timer
最初就可以访问countDownTimer
。在下一次渲染中,状态会发生改变,并且将创建一个新的timer
函数来访问已更改的状态,但是间隔仍将调用旧的timer
函数。 - ian