Reputation: 2023
I have uploaded my code here in https://codesandbox.io/s/blissful-lehmann-o4thw?file=/src/Layout.tsx
I am trying to do a stopwatch. But working not as expected due to hook issue.
const startTimer = async () => {
setDisableStart(true);
setDisableStop(false);
const rightNowTime = await Date.now().toString();
setCurrentTime(rightNowTime);
interval = setInterval(() => {
calculateTime();
}, 1);
};
I can see problem with setCurrentTime(rightNowTime) is not updating current time
Please, somebody, suggest
Upvotes: 0
Views: 430
Reputation: 202915
You are making things a bit more complicated than they need to be. I suggest storing only a start time and a current "tick" and compute the derived "state" of the minutes, seconds, and milliseconds between these two timestamps.
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>
);
};
Upvotes: 1