javascript React JS - 实时时钟更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32880484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:51:36  来源:igfitidea点击:

React JS - Live clock update

javascriptreactjs

提问by amoeboar

I've got a clock function that gets time and renders out the hours, minutes and seconds, and I'm trying to update the data on screen in real time, but for some reason my setInterval function isn't doing what I expect.

我有一个时钟函数,它可以获取时间并显示小时、分钟和秒,我正在尝试实时更新屏幕上的数据,但由于某种原因,我的 setInterval 函数没有按照我的预期运行。

I thought react's render method is supposed to render data in real time. Do I need ajax for this? Can anyone offer some advice?

我认为反应的渲染方法应该实时渲染数据。我需要为此使用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>
    )
  }
});

回答by KevinH

The official React Docs describe exactly what you need (and even explains why you should do it as described):

官方的 React Docs 准确地描述了你需要什么(甚至解释了为什么你应该像描述的那样做):

--> React Docs: State and Lifecycle

--> React 文档:状态和生命周期

Example on CodePen:

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')
);

回答by noveyak

There seems to be a couple problems with your code. First is the closing div in the render function which causes your element to not even render.

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

Next you might want to take a look at state/props and React general lifecycle methods to get a better idea of program flow. The setInterval should be put in componentDidMount so its not called every time your component renders and creates a lot of timers. It also might help to put hours, minutes, and seconds as state so that way when these change your component re-renders automatically.

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

I modified your code below and put an example on jsfiddle. It does not print the seconds properly (just like in your getTime method) but hopefully it will give you a better idea of how logic should flow.

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

https://jsfiddle.net/rpg6t4uc/

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>
    )
  }
});

回答by Eliecer Chicott

Update of "TheSchecke" answer to show UTC date on format "YYYY-MM-DD HH:mm:ss":

更新“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')
);