Hey is a decentralized and permissionless social media app built with Lens Protocol 🌿
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: refactor CountdownTimer component to improve time calculation and interval management, ensuring accurate countdown and cleanup on unmount

yoginth.com 19290b22 b3d6d0a6

verified
+38 -10
+38 -10
apps/web/src/components/Shared/CountdownTimer.tsx
··· 1 - import { useEffect, useState } from "react"; 1 + import { useCallback, useEffect, useRef, useState } from "react"; 2 2 3 3 type TimeLeft = { 4 4 days: number; ··· 12 12 } 13 13 14 14 const CountdownTimer = ({ targetDate }: CountdownTimerProps) => { 15 - const calculateTimeLeft = (): TimeLeft => { 15 + const intervalRef = useRef<NodeJS.Timeout | null>(null); 16 + const targetTimeRef = useRef<number>(new Date(targetDate).getTime() - 30000); 17 + 18 + const calculateTimeLeft = useCallback((): TimeLeft => { 16 19 const now = new Date().getTime(); 17 - const target = new Date(targetDate).getTime() - 30000; // Subtract 30 seconds 18 - const timeDiff = target - now; 20 + const timeDiff = targetTimeRef.current - now; 19 21 20 22 if (timeDiff <= 0) { 21 23 return { days: 0, hours: 0, minutes: 0, seconds: 0 }; ··· 27 29 const seconds = Math.floor((timeDiff / 1000) % 60); 28 30 29 31 return { days, hours, minutes, seconds }; 30 - }; 32 + }, []); 31 33 32 34 const [timeLeft, setTimeLeft] = useState<TimeLeft>(calculateTimeLeft); 33 35 34 36 useEffect(() => { 35 - const timer = setInterval(() => { 36 - setTimeLeft(calculateTimeLeft()); 37 - }, 1000); 37 + targetTimeRef.current = new Date(targetDate).getTime() - 30000; 38 + setTimeLeft(calculateTimeLeft()); 39 + }, [targetDate, calculateTimeLeft]); 38 40 39 - return () => clearInterval(timer); 40 - }, [targetDate]); 41 + useEffect(() => { 42 + const updateTimer = () => { 43 + const newTimeLeft = calculateTimeLeft(); 44 + setTimeLeft(newTimeLeft); 45 + 46 + // Stop interval when countdown reaches zero 47 + if ( 48 + newTimeLeft.days === 0 && 49 + newTimeLeft.hours === 0 && 50 + newTimeLeft.minutes === 0 && 51 + newTimeLeft.seconds === 0 52 + ) { 53 + if (intervalRef.current) { 54 + clearInterval(intervalRef.current); 55 + intervalRef.current = null; 56 + } 57 + } 58 + }; 59 + 60 + intervalRef.current = setInterval(updateTimer, 1000); 61 + 62 + return () => { 63 + if (intervalRef.current) { 64 + clearInterval(intervalRef.current); 65 + intervalRef.current = null; 66 + } 67 + }; 68 + }, [calculateTimeLeft]); 41 69 42 70 const formatTimeValue = (value: number, label: string): string => { 43 71 return value > 0 ? `${value}${label} ` : "";