'How to update a clock every second in React js recursively?

I am trying to create a react app that updates every second. If I use setInterval inside the render, it may overload the task. So, I want to call the setInterval function only after the clock has finished rendering. When I tried running the code, it says that the maximum recursion depth has been exceeded. I know it's an infinite loop but since it will execute only after waiting for 1 second, is there a way to get around this? Here is the code:

import React from 'react';

export class Fluctuation extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0,
            time: new Date(),
        }
    }

    updateTime() {
        this.setState({time: new Date()})
    }
    
    updateTimeRecursively() {
        this.updateTime();
        setInterval(this.updateTime(), 1000);
    }

    
    render() {
        this.updateTimeRecursively();
        return (
            <main>
                <div className="time-container">
                    <div className="hours">{this.state.time.getHours()}</div>:
                    <div className="minutes">{this.state.time.getMinutes()}</div>:
                    <div className="seconds">{this.state.time.getSeconds()}</div>
                </div>
                <button onClick={() => this.updateTime()}>Update Time</button>
            </main>
        )
    }
}


Solution 1:[1]

Few things to correct,

  1. Remove calling updateTimeRecursively from the render method it causes to exceed the maximum update depth.
  2. Call it within componentDidMount lifecycle method.
  3. setInterval accepts a function, not a function call.

class Fluctuation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      time: new Date()
    };
  }

  updateTime = () => {
    this.setState({ time: new Date() });
  };

  updateTimeRecursively() {
    this.updateTime();
    setInterval(this.updateTime, 1000);
  }

  componentDidMount = () => {
    this.updateTimeRecursively();
  };

  render() {
    return (
      <main>
        <div className="time-container">
          <div className="hours">{this.state.time.getHours()}</div>:
          <div className="minutes">{this.state.time.getMinutes()}</div>:
          <div className="seconds">{this.state.time.getSeconds()}</div>
        </div>
        <button onClick={() => this.updateTime()}>Update Time</button>
      </main>
    );
  }
}

ReactDOM.render(<Fluctuation/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Solution 2:[2]

Solution for a functional component -

import React, { useEffect } from "react";

export default function App() {
  const [time, setTime] = React.useState('');

  useEffect(()=>{
    setInterval(()=>{ let nwDate = new Date(); setTime(nwDate)}, 1000);
  },[])

  return (
    <div className="App">
      <h1>{time.toString()}</h1>
    </div>
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Amila Senadheera
Solution 2