ndresx / react-countdown

A customizable countdown component for React.
MIT License
746 stars 69 forks source link

countdown won't restart on it's own without reloading page using if else statement #255

Closed leutrimdemiri closed 2 weeks ago

leutrimdemiri commented 3 months ago

Hi, I'm using if else statement for the next prayer time but when the next prayer time passes countdown won't restart on itself

check the code example: https://codesandbox.io/p/sandbox/prayer-times-n4rz48?file=%2Fsrc%2FApp.js%3A5%2C27

here's my code

let nextPrayerName = null;
let nextPrayerTime = null;
let currentTime = moment().format();

const fajr = moment("05/26/2024 03:20", "MM/DD/YYYY HH:mm").format();
const dhuhr = moment("05/26/2024 13:05", "MM/DD/YYYY HH:mm").format();

if (currentTime < fajr) {
  nextPrayerTime = fajr;
  nextPrayerName = "Fajr";
} else if (currentTime < dhuhr) {
  nextPrayerTime = dhuhr;
  nextPrayerName = "Dhuhr";
} else {
  // I have another implemented code for the next day just using this for example.
}
  const renderer = ({ hours, minutes, seconds, completed }) => {
    if (completed) {
      return <span>finished</span>;
    } else {
      return (
        <span>
          {hours}:{minutes}:{seconds}
        </span>
      );
    }
  };
  return (
    <div className="App">
      <Countdown
        key={nextPrayerTime}
        date={nextPrayerTime}
        autoStart={true}
        renderer={renderer}
        zeroPadTime={2}
      />
    </div>
  );
ndresx commented 1 month ago

Hi, half of the code responsible for switching the time seems to be outside the App component or any React context and is, therefore, already computed at compile time. This means that the checks will only be executed once and then never again.

leutrimdemiri commented 1 month ago

Hi, half of the code responsible for switching the time seems to be outside the App component or any React context and is, therefore, already computed at compile time. This means that the checks will only be executed once and then never again.

So in your opinion you have to put the code inside app component which executes each time the next time passes? I didn't know that until now, perhaps no need to use useEffect or setInterval in this case?

ndresx commented 1 month ago

Yes, although the codesandbox doesn't work anymore, based on your initial comment "when the next prayer time passes countdown won't restart on itself", it sounded to me as if you would want the countdown/App component to change their behavior based on the datetime calculations that are happening outside right now (with the if conditions, etc.) unless some code lines got shifted there.

That would need to change if you want this to be considered without having to refresh the page, and so the code would need to be put or invoked from somewhere that knows that the time is changing. The way it works right now is that, e.g., currentTime gets computed and assigned once and then never again. At least the example looks like that to me.

Kam125 commented 1 month ago

Hey, My question is similar to this one. I'm using this code but the timer shows correct pending time but not ticking. Here's ref code

const [remainingTime, setRemainingTime] = useState<any>( new Date(Date.now() + 20 * 1000) );

const calculateRemainingTime = () => { const currentTime = moment(); let gtdEndTime = moment.unix(Number(roundTimes?.[1]?.toString() || 0)); let fcfsEndTime = moment.unix(Number(roundTimes?.[3]?.toString() || 0)); let revealNFTTime = moment.unix(Number(revealTime?.toString() || 0)); if (findRound() === "GTD") { return gtdEndTime?.toDate(); } else if (findRound() === "FCFS") { return fcfsEndTime?.toDate(); } else { if (currentTime.isAfter(fcfsEndTime) && revealNFTTime) { return revealNFTTime?.toDate(); } else { return new Date(); } } };

useEffect(() => { setRemainingTime(calculateRemainingTime()); }, [roundTimes, currentRound, revealTime]);

<Countdown date={remainingTime} key={456} onStart={() => { console.log("Countdown started"); }} renderer={renderer} onComplete={() => { setReachedMaxTime(true); }} />

It's been 2 day's and my production build is pending due to this issue. @ndresx Thanks

ndresx commented 1 month ago

Hi @Kam125, did you try using remainingTime for the key prop, does this change anything?

Kam125 commented 1 month ago

Thanks man for a quick response, you saved me. I was using random key for countdown. I tried this & it's working perfectly.

ndresx commented 2 weeks ago

I'll close this issue. If you have any additional or other questions, please feel free to re-open or create a new one!