Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a running clock using moment & moment-timezone in react

I'm trying to create a react component that renders a ticking clock. I'm using moment and moment-timezone for different time-zones. I was able to create a component with a static clock (doesn't increment), but I'm unable to create a ticking clock. Code is below:

import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import moment from 'moment';
import 'moment-timezone';

export default class TimeClock extends React.Component {

    constructor(props) {
      super(props);
      this.state = { time: moment().clone().tz(this.props.timezone).toLocaleString() };
      this.displayTime = this.displayTime.bind(this);
    }

    displayTime(){
        //let now = moment();
        //let location = now.clone().tz(this.props.timezone);
        this.setState({
            time: moment().clone().tz(this.props.timezone).toLocaleString()
        });
        //return location.toLocaleString();
    }
    render(){
        //let now = moment();
        //let location = now.clone().tz(this.props.timezone);
        //let timezone = this.props.timezone;
        return (
            <div>
                <p>{this.props.timezone}</p>
                <p>{setInterval(this.displayTime,1000)}</p>
            </div>
        );
    }
}

Note: its being passed a prop (timezone) from App.js, a parent component.

Current code outputs the following:

Australia/Melbourne

#######

where ####### represents some number that started at 5 or 6 and is increasing rapidly.

Can someone explain what I'm doing wrong?

Edit: soon after posting this question, I found the following link (Where to apply my moment() function in a react component?), which I adapted to my code and got it working, but I don't understand why my attempt didn't work. I'm new to react.

like image 559
lycan1385 Avatar asked Mar 03 '26 16:03

lycan1385


1 Answers

Your code does not render anything related to the current time. This line:

<p>{setInterval(this.displayTime,1000)}</p>

does not print the current time - it displays created interval's ID, because that's what is returned by setInterval() function.

So, first of all, you should change this line to display the time, based on Component's state. This can be done like this:

<p>{this.state.time}</p>

Another thing you have to do is to properly create the interval. Setting it in render() method is not a good idea, because you will create a new interval

componentDidMount() {
    // Arrow function allows you to use "this" in context of the Component
    this.interval = setInterval(() => {
        this.displayTime();
    }), 1000);
}

(you should also remember to deactivate the interval once component is removed from the view).

like image 195
mdziekon Avatar answered Mar 05 '26 06:03

mdziekon