DEV Community

Cover image for Building a Dynamic Deadline Countdown Timer in React.js
Shreyash Kumar
Shreyash Kumar

Posted on

Building a Dynamic Deadline Countdown Timer in React.js

In web development, displaying a countdown timer is a common feature for e-commerce sites, especially for sales events or limited-time offers. The challenge is to create a dynamic and visually appealing countdown timer without relying on external libraries, ensuring efficient performance and seamless integration into any React application.

Countdown timers are essential for creating urgency in sales and promotional events. They encourage users to take action before the timer runs out, making them a powerful tool in marketing strategies. In this post, I'll walk you through the process of building a dynamic countdown timer using React.js and Tailwind CSS. We'll explore how to calculate the remaining time until a specific deadline and display it in a user-friendly format.

We'll build a reusable countdown timer component in React.js that calculates the remaining time until a specified deadline and updates the UI every second. The component will be styled using Tailwind CSS to ensure a modern and responsive design. The goal is to create a timer that displays the number of days, hours, minutes, and seconds left until the event ends.

Explanation of Implementation:

Step 1: Setting Up the React Component

We'll start by creating a Counter component. This component will manage the state for the days and the time left (hours, minutes, and seconds) until the deadline.

import React, { useState, useEffect } from 'react';

const Counter = () => {
    const deadline = new Date('December 31 2024');
    const [days, setDays] = useState(0);
    const [timer, setTimer] = useState({
        hours: 0,
        minutes: 0,
        seconds: 0,
    });
Enter fullscreen mode Exit fullscreen mode

Here, deadline is the target date, and useState is used to store the days left and the time components (hours, minutes, seconds).

Step 2: Calculating Time Left

Inside the useEffect hook, we define a function calculateTimeLeft that calculates the time remaining until the deadline. The function calculates the difference between the current time and the deadline, then converts this difference into days, hours, minutes, and seconds.

useEffect(() => {
    const calculateTimeLeft = () => {
        const currentDate = new Date();
        const timeLeft = deadline.getTime() - currentDate.getTime();

        const days = Math.floor(timeLeft / (24 * 60 * 60 * 1000));
        const hours = 23 - currentDate.getHours();
        const minutes = 59 - currentDate.getMinutes();
        const seconds = 59 - currentDate.getSeconds();

        setDays(days);
        setTimer({ hours, minutes, seconds });
    };

    calculateTimeLeft();
    const intervalId = setInterval(calculateTimeLeft, 1000);

    return () => clearInterval(intervalId);
}, [deadline]);
Enter fullscreen mode Exit fullscreen mode

This hook ensures that the time left is recalculated every second by using setInterval to update the state, which triggers a re-render of the component.

Step 3: Displaying the Countdown Timer

The calculated values are then displayed using the TimeBox component, which renders each time unit (days, hours, minutes, seconds) in a visually appealing format.

return (
    <div className='w-full h-screen bg-black flex items-center justify-center'>
        <div className="w-full h-auto bg-black grid grid-cols-1 gap-8 place-items-center">
            <h1 className="text-5xl font-extrabold text-white">Sales Ends In</h1>
            <div className="w-fit h-auto overflow-hidden grid grid-cols-4 gap-4 place-items-center">
                <TimeBox label="Days" value={days} />
                <TimeBox label="Hours" value={timer.hours} />
                <TimeBox label="Minutes" value={timer.minutes} />
                <TimeBox label="Seconds" value={timer.seconds} />
            </div>
        </div>
    </div>
);
Enter fullscreen mode Exit fullscreen mode

The TimeBox component is defined separately to make the code modular and reusable. Each TimeBox displays a label (e.g., "Days") and the corresponding value.

const TimeBox = ({ label, value }) => (
    <div className="w-24 h-24 bg-red rounded-xl p-4">
        <p className="text-center text-yellow font-bold">{label}</p>
        <p className="text-center font-bold text-2xl text-white">{value}</p>
    </div>
);
Enter fullscreen mode Exit fullscreen mode

Step 4: Styling with Tailwind CSS

We use Tailwind CSS to style the countdown timer. The use of utility classes like bg-black, text-white, text-5xl, and rounded-xl helps in creating a modern and responsive UI with minimal CSS.

By following this approach, you can create a highly customizable and reusable countdown timer component for any React application. This solution is efficient, avoids unnecessary re-renders, and offers a clean and modern design with Tailwind CSS. Whether you're working on an e-commerce site or any other project requiring a countdown, this timer component will seamlessly integrate and elevate the user experience.

Top comments (2)

Collapse
 
cookiemonsterdev profile image
Mykhailo Toporkov 🇺🇦 • Edited

Wow, that is too complicated, countdown is not a problem of calculation it is rather problem of proper time formating.

1). The time left calculation can be reduced to just something like:

const [time, setTime] = useState<number>(1000000);

useEffect(() => {
   const interval = setInterval(()=>{
        if(time > 1000) { 
            setTime(prev => prev - 1000)
        } else  { 
            setTime(0);
            clearInterval(interval)
        }   
    }, 1000)

   return () => {
       clearInterval(interval)
   }
}, [])

Enter fullscreen mode Exit fullscreen mode

2). Now that you have time in milliseconds, you can do whatever you want, but rather than calculate milliseconds, seconds, minutes, and hours by yourself use Intl.DateTimeFormat


const options = {
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
};

const timeFormatter = new Intl.DateTimeFormat('en-US', options)

<div>{timeFormatter.format(new Date(time))}</div>
Enter fullscreen mode Exit fullscreen mode

This way is easier)))

Collapse
 
axorax profile image
Axorax

cool