DEV Community

Max-Xampy
Max-Xampy

Posted on

React JS: Countdown timer restart when page is reloaded Simple solution

React <Countdown/> is a customizable countdown component for React.

It seems that we lost the counter if we reload the browser page. To avoid that we will use the local storage to persist our timer data.

We will use the package example source code
https://codesandbox.io/s/sad-zhukovsky-hs7hc

You can find the final solution here
https://codesandbox.io/s/serene-leftpad-40e7e

But first, we verify that we have installed the required packages and have imported them. Our code header must look like this

import React from "react";
import ReactDOM from "react-dom";
import Countdown from "react-countdown";
import { useState, useEffect } from "react";
Enter fullscreen mode Exit fullscreen mode

Next is our counter renderer function component.

// Random component
const Completionist = () => <span>You are good to go!</span>;

// Renderer callback with condition
const renderer = ({ hours, minutes, seconds, completed }) => {
  if (completed) {
    // Render a complete state
    return <Completionist />;
  } else {
    // Render a countdown
    return (
      <span>
        {hours}:{minutes}:{seconds}
      </span>
    );
  }
};
Enter fullscreen mode Exit fullscreen mode

Our next step will be a function to read data from local storage

const getLocalStorageValue = (s) => localStorage.getItem(s);
Enter fullscreen mode Exit fullscreen mode

Next we create our App function component and defined required data. The most important data is the delay value.

const App = () => {
  const [data, setData] = useState(
    { date: Date.now(), delay: 60000 } //60 seconds
  );
  const wantedDelay = 60000; //60 s

  return (
    <div>
      <Countdown
        date={data.date + data.delay}
        renderer={renderer}
        onStart={(delta) => {
          //Save the end date
          if (localStorage.getItem("end_date") == null)
            localStorage.setItem(
              "end_date",
              JSON.stringify(data.date + data.delay)
            );
        }}
        onComplete={() => {
          if (localStorage.getItem("end_date") != null)
            localStorage.removeItem("end_date");
        }}
      />
    </div>
  );
Enter fullscreen mode Exit fullscreen mode

Now our main problem is how to handle the browser page reloaded; for that we will use a react hook (with class component it will be componentDidMount function).

  //[START] componentDidMount
  //Code runs only one time after each reloading
  useEffect(() => {
    const savedDate = getLocalStorageValue("end_date");
    if (savedDate != null && !isNaN(savedDate)) {
      const currentTime = Date.now();
      const delta = parseInt(savedDate, 10) - currentTime;

      //Do you reach the end?
      if (delta > wantedDelay) {
        //Yes we clear uour saved end date
        if (localStorage.getItem("end_date").length > 0)
          localStorage.removeItem("end_date");
      } else {
        //No update the end date  
        setData({ date: currentTime, delay: delta });
      }
    }
  }, []);
  //[END] componentDidMount

Enter fullscreen mode Exit fullscreen mode

Instead of using localstorage, we can use a remote server or anything else. The most important is to save our end date of the count down.

Thanks

Discussion (1)

Collapse
johnmethew18 profile image
john methew

Thanks for sharing, the sample code i will tested to sort out local storage issue