skip to Main Content
Hi everyone facing one issue in my react application where I have array of list timestamp's ex:([1651234567, 1651234568, 1651234569]) which I need to convert in to hours minutes & seconds like Ex:([17:46:7, 17:46:8, 17:46:9]) each seconds timer should increase with help of But in my current scenario this logic is not working.

The below code I have defined timestamp state array & also In useEffect I’m calling setInterval time on every 1 second. But below code timer remain constant. Please help on this.

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>

const ConvertTimer = () => {
    const [timestamp, setTimestamp] = useState([1651234567, 1651234568, 1651234569]);
  const [timeLeft, setTimeLeft] = useState([]);

  useEffect(() => {
    const timer = setInterval(() => {
      const newTimeLeft = timestamp.map((timestamp) => {
        const date = new Date(timestamp * 1000);
        const hours = date.getHours();
        const minutes = date.getMinutes();
        const seconds = date.getSeconds();
        return `${hours}:${minutes}:${seconds}`;
      });
      setTimeLeft(newTimeLeft);
    }, 1000);

    return () => clearInterval(timer);

    
  }, [timestamp]);
  return (
    <div>
      <h1>Time Left</h1>
      <ul>
        {timeLeft.map((time) => (
          <li key={time}>{time}</li>
        ))}
      </ul>
    </div>
  )
}

  

2

Answers


  1. I think your issue is that you always recompute the same thing so you render the same result.

    If I understood what you want to do, you should compute the time left inside your setInterval. It means you should assess the difference between the timestamp and the current time.

    Something like below might work:

    const ConvertTimer = () => {
        const [timestamp, setTimestamp] = useState([1651234567, 1651234568, 1651234569]);
      const [timeLeft, setTimeLeft] = useState([]);
    
      useEffect(() => {
        const timer = setInterval(() => {
          const newTimeLeft = timestamp.map((timestamp) => {
            /* V we compute the time left below */
            const date = new Date((new Date(timestamp * 1000)).getTime() - (new Date()).getTime());
            const hours = date.getHours();
            const minutes = date.getMinutes();
            const seconds = date.getSeconds();
            return `${hours}:${minutes}:${seconds}`;
          });
          setTimeLeft(newTimeLeft);
        }, 1000);
    
        return () => clearInterval(timer);
    
        
      }, []);
      
      return (
        <div>
          <h1>Time Left</h1>
          <ul>
            {timeLeft.map((time) => (
              <li key={time}>{time}</li>
            ))}
          </ul>
        </div>
      )
    }
    
    

    Live demo there: https://codepen.io/friedrith/pen/vYMYmBy

    Login or Signup to reply.
  2. I think one of the best solution is to use dayjs npm package.
    They have a lot of built in functions, plugins and internationalization as well.

    As an example I can provide you following code, but you definitely can discover their documentation and adapt your code for your needs.

    import React, { useState, useEffect } from 'react'
    import dayjs from 'dayjs'
    import duration from 'dayjs/plugin/duration'
    
    
    export default function Timer(){
      dayjs.extend(duration)// you can also play with duration
    
      const timestamps: number[] = [1651234567, 1651234568, 1651234569]
      const [timeLeft, setTimeLeft] = useState<string[]>()
    
      useEffect(() => {
        const timer = setInterval(() => {
          const newTimeLeft = timestamps.map((timestamp) => {
            const now = dayjs()
            const targetTime = dayjs.unix(timestamp)
            const duration = dayjs.duration(targetTime.diff(now))
            return duration.format('HH:mm:ss')
          })
          setTimeLeft(newTimeLeft)
        }, 1000)
        return () => clearInterval(timer)
      }, [])
    
      return (
        <>
        <div>
          <h1>Time Left</h1>
          <ul>
            {timeLeft?.map((time) => (
              <li key={time}>{time}</li>
            ))}
          </ul>
        </div>
        </>
      )
    }
    

    You can find their documentation here

    P.S. be careful and keep this component small. React is an component based framework, each time you setTimeLeft it calls re-rendering of this component.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search