useState 在实现秒表时在字符串中给定日期时第一次不起作用
useState doesn't work first time when given date in string while implementing stop watch
我已经在 https://codesandbox.io/s/blissful-lehmann-o4thw?file=/src/Layout.tsx
中上传了我的代码
我想做一个秒表。但由于钩子问题,工作不如预期。
const startTimer = async () => {
setDisableStart(true);
setDisableStop(false);
const rightNowTime = await Date.now().toString();
setCurrentTime(rightNowTime);
interval = setInterval(() => {
calculateTime();
}, 1);
};
我可以看到 setCurrentTime(rightNowTime) 没有更新当前时间的问题
拜托,有人建议
你让事情变得比他们需要的更复杂了。我建议只存储开始时间和当前“滴答声”,并计算这两个时间戳之间的分钟、秒和毫秒的派生“状态”。
const App = () => {
const [startTime, setStartTime] = useState<number>(0);
const [currentTime, setCurrentTime] = useState<number>(0);
// Store interval id in React ref
const intervalRef = useRef<number | undefined>();
const [disableStop, setDisableStop] = useState<boolean>(true);
const [disableReset, setDisableReset] = useState<boolean>(true);
const [disableStart, setDisableStart] = useState<boolean>(false);
// Return cleanup function to clear any running intervals
// on the event of component unmount
useEffect(() => {
return () => clearInterval(intervalRef.current);
}, []);
const calculateTime = () => {
setCurrentTime(Date.now());
};
const startTimer = () => {
setDisableStart(true);
setDisableStop(false);
// Only update start time if reset to 0
if (!startTime) {
setStartTime(Date.now());
}
// Invoke once immediately
calculateTime();
// Instantiate interval
intervalRef.current = setInterval(() => {
calculateTime();
}, 1);
};
const stopTimer = () => { ... };
const resetTimer = () => { ... };
// Compute the minutes, seconds, and milliseconds from time delta
const delta: number = currentTime - startTime; // in ms
const minutes: string = Math.floor(delta / (1000 * 60)).toString();
const seconds: string = (Math.floor(delta / 1000) % 60)
.toString()
.padStart(2, "0");
const milliseconds: string = (delta % 1000).toString().padStart(3, "0");
return (
<React.Fragment>
<div className="container">
<h1>Stop Watch</h1>
</div>
<Layout seconds={seconds} minutes={minutes} milliseconds={milliseconds} />
<Buttons ... />
</React.Fragment>
);
};
我已经在 https://codesandbox.io/s/blissful-lehmann-o4thw?file=/src/Layout.tsx
中上传了我的代码我想做一个秒表。但由于钩子问题,工作不如预期。
const startTimer = async () => {
setDisableStart(true);
setDisableStop(false);
const rightNowTime = await Date.now().toString();
setCurrentTime(rightNowTime);
interval = setInterval(() => {
calculateTime();
}, 1);
};
我可以看到 setCurrentTime(rightNowTime) 没有更新当前时间的问题
拜托,有人建议
你让事情变得比他们需要的更复杂了。我建议只存储开始时间和当前“滴答声”,并计算这两个时间戳之间的分钟、秒和毫秒的派生“状态”。
const App = () => {
const [startTime, setStartTime] = useState<number>(0);
const [currentTime, setCurrentTime] = useState<number>(0);
// Store interval id in React ref
const intervalRef = useRef<number | undefined>();
const [disableStop, setDisableStop] = useState<boolean>(true);
const [disableReset, setDisableReset] = useState<boolean>(true);
const [disableStart, setDisableStart] = useState<boolean>(false);
// Return cleanup function to clear any running intervals
// on the event of component unmount
useEffect(() => {
return () => clearInterval(intervalRef.current);
}, []);
const calculateTime = () => {
setCurrentTime(Date.now());
};
const startTimer = () => {
setDisableStart(true);
setDisableStop(false);
// Only update start time if reset to 0
if (!startTime) {
setStartTime(Date.now());
}
// Invoke once immediately
calculateTime();
// Instantiate interval
intervalRef.current = setInterval(() => {
calculateTime();
}, 1);
};
const stopTimer = () => { ... };
const resetTimer = () => { ... };
// Compute the minutes, seconds, and milliseconds from time delta
const delta: number = currentTime - startTime; // in ms
const minutes: string = Math.floor(delta / (1000 * 60)).toString();
const seconds: string = (Math.floor(delta / 1000) % 60)
.toString()
.padStart(2, "0");
const milliseconds: string = (delta % 1000).toString().padStart(3, "0");
return (
<React.Fragment>
<div className="container">
<h1>Stop Watch</h1>
</div>
<Layout seconds={seconds} minutes={minutes} milliseconds={milliseconds} />
<Buttons ... />
</React.Fragment>
);
};