React JS - 实时时钟更新

时间:2015-10-01 06:07:32

标签: javascript reactjs

我有时钟功能可以获得时间并显示小时,分钟和秒钟,并且我试图实时更新屏幕上的数据,但出于某种原因我的setInterval函数不是& #39;做我期望的事。

我认为反应的渲染方法应该实时渲染数据。我需要ajax吗?有人可以提供一些建议吗?

var CityRow = React.createClass({

  render: function() {

    var currentdate = new Date();

    function getTime() {
      // get local time based on the UTC offset
      this.hours = currentdate.getUTCHours() + parseInt(this.props.UTCOffset);    

      // correct for number over 24, and negatives
      if( this.hours >= 24 ){ this.hours = this.hours - 24; }
      if( this.hours < 0   ){ this.hours = this.hours + 12; }

      // add leading zero, first convert hours to string
      this.hours = this.hours + "";
      if( this.hours.length == 1 ){ this.hours = "0" + this.hours; }

      // minutes are the same on every time zone
      this.minutes = currentdate.getUTCMinutes();

      // add leading zero, first convert hours to string
      this.minutes = this.minutes + "";
      if( this.minutes.length == 1 ){ this.minutes = "0" + this.minutes; }

      this.seconds = currentdate.getUTCSeconds();
    }

    window.setInterval(function () {
      getTime();
    }, 1000);

    return(
      <div className="city-row" ref="cityRow">
        <span className="city-time">{this.hours}:{this.minutes}:{this.seconds}</span>
        </div>
      </div>
    )
  }
});

5 个答案:

答案 0 :(得分:11)

官方的React Docs准确描述了您的需求(甚至可以解释为什么您应该如上所述):

--> React Docs: State and Lifecycle

Example on CodePen

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

答案 1 :(得分:10)

您的代码似乎存在一些问题。首先是渲染函数中的结束div,它会导致元素甚至无法渲染。

接下来,您可能需要查看state / props和React一般生命周期方法,以更好地了解程序流。 setInterval应该放在componentDidMount中,这样每次组件渲染时都不会调用它,并创建大量的计时器。它还可能有助于将小时,分钟和秒作为状态,以便在这些更改组件时自动重新渲染。

我在下面修改了你的代码并在jsfiddle上放了一个例子。它没有正确打印秒(就像你的getTime方法一样),但希望它能让你更好地了解逻辑应该如何流动。

https://jsfiddle.net/rpg6t4uc/

var CityRow = React.createClass({
  setTime: function(){

    var currentdate = new Date();
    var hours = currentdate.getUTCHours() + parseInt(this.props.UTCOffset);    

      // correct for number over 24, and negatives
      if( hours >= 24 ){ hours -= 24; }
      if( hours < 0   ){ hours += 12; }

      // add leading zero, first convert hours to string
      hours = hours + "";
      if( hours.length == 1 ){ hours = "0" + hours; }

      // minutes are the same on every time zone
      var minutes = currentdate.getUTCMinutes();

      // add leading zero, first convert hours to string
      minutes = minutes + "";
      if( minutes.length == 1 ){ minutes = "0" + minutes; }

      seconds = currentdate.getUTCSeconds();
      console.log(hours, minutes, seconds)
      this.setState({
        hours: hours,
        minutes: minutes,
        seconds: seconds
      });
  },
  componentWillMount: function(){
    this.setTime();
  },
  componentDidMount: function(){
     window.setInterval(function () {
      this.setTime();
    }.bind(this), 1000);
  },
  render: function() {

    return(
      <div className="city-row" ref="cityRow">
        <span className="city-time">{this.state.hours}:{this.state.minutes}:{this.state.seconds}</span>
      </div>
    )
  }
});

答案 2 :(得分:0)

更新“TheSchecke”答案以格式“YYYY-MM-DD HH:mm:ss”显示UTC日期:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    const ISOStringDate = this.state.date.toISOString();
    return (
        <div>
            <h1>UTC Time:</h1>
            <h2>{ISOStringDate.substring(0, 19).replace('T', ' ')}</h2>
        </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

答案 3 :(得分:0)

class Clock extends React.Component {
    
   state ={time:null}
    
    componentDidMount() {
        setInterval(() => {
            this.setState({time:new Date().toLocaleTimeString()})}, 1000)
       }

    render() {
            return (
            <div className="time">
                The time is: {this.state.time}
            </div>
             );
         }
  }

  ReactDOM.render( 
      <Clock />,
      document.getElementById('root') );

答案 4 :(得分:0)

import React, { Component } from "react";

class Clock extends Component {
    constructor (props) {
        super(props);

        this.state = {
            dateClass: new Date()
        }

        this.time = this.state.dateClass.toLocaleTimeString();
        this.hourMin = this.time.length === 10? this.time.slice(0) : this.time.slice(0,5);
    }

    setTime = () => {
        this.setState({
            dateClass: new Date()
        })
        this.time = this.state.dateClass.toLocaleTimeString();
        this.hourMin = this.time.length === 10? this.time.slice(0) : this.time.slice(0,5);
    }

    componentDidMount () {
        setInterval(this.setTime, 1000)
    }
    
    render () {
        return (
            <div>
                {this.hourMin}
            </div>
        )
    }
}

export default Clock;

嘿,我有更简单的方法。