Home > Software engineering >  How can I let update the time every second?
How can I let update the time every second?

Time:07-23

I have a React App that counts years, days, hours, minutes and second from a given date.

Timer.js

function Timer() {

    const startDate = new Date(2000, 0, 0, 0, 0, 0, 0);
    var now = new Date();
    var diff = now.getTime() - startDate.getTime();

    var years = Math.floor((diff / (1000 * 60 * 60 * 24 * 365)));
    diff = diff % (1000 * 60 * 60 * 24 * 365);

    var days = Math.floor((diff / (1000 * 60 * 60 * 24)));
    diff = diff % (1000 * 60 * 60 * 24);

    var hrs = Math.floor((diff / (1000 * 60 * 60)));
    diff = diff % (1000 * 60 * 60);

    var min = Math.floor((diff / (1000 * 60)));
    diff = diff % (1000 * 60);

    var sec = now.getSeconds(Math.floor((diff / (1000))));
    diff = diff % (1000);

    return (<div>
        {years} years,
        <br /> {days} days,
        <br /> {hrs} hours,
        <br /> {min} minutes,
        <br /> {sec} seconds   
    </div>);

}
export default Timer;

App.js

import Timer from './Timer';
function App() {
  return (
    <div>
          <div>
            <Timer />
          </div>
    </div>
  );
}

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

reportWebVitals();

I get an output like this:

22 years,
209 days,
50 minutes,
19 hours,
13 seconds

I want it to be updated every second without reloading the page. I tried with

setTimeout(timer, 1000); 

in the Timer function but it didn't work.

What do I need?

CodePudding user response:

You just need to save the now object as a state variable and update it within useEffect hook, using setTimeout.

Update: Much more clear version of the code:

function Timer() {
  const [nowMs, setNowMs] = useState(Date.now());

  const startDateMs = useMemo(() => {
    return new Date(2000, 0, 0, 0, 0, 0, 0).getTime();
  }, []);

  const { years, days, hrs, min, sec } = useMemo(() => {
    let diff = nowMs - startDateMs;

    const years = Math.floor(diff / (1000 * 60 * 60 * 24 * 365));
    diff = diff % (1000 * 60 * 60 * 24 * 365);

    const days = Math.floor(diff / (1000 * 60 * 60 * 24));
    diff = diff % (1000 * 60 * 60 * 24);

    const hrs = Math.floor(diff / (1000 * 60 * 60));
    diff = diff % (1000 * 60 * 60);

    const min = Math.floor(diff / (1000 * 60));
    diff = diff % (1000 * 60);

    const sec = Math.floor(diff / 1000);
    diff = diff % 1000;
    return { years, days, hrs, min, sec };
  }, [nowMs, startDateMs]);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setNowMs(Date.now());
    }, 1000);
    return () => clearInterval(intervalId);
  }, []);

  return (
    <div>
      {years} years,
      <br /> {days} days,
      <br /> {hrs} hours,
      <br /> {min} minutes,
      <br /> {sec} seconds
    </div>
  );
}

Edit epic-babbage-57yovt

CodePudding user response:

you can use

 [time, setTime] = useState();
 useEffect(() => {
    setTimeout(() => {
       // do your stuff and call setTime() to rerender this component
    }, 1000); 
  }, []);
  • Related