在react组件中应用moment()函数的位置

Where to apply my moment() function in a react component?

本文关键字:函数 位置 moment react 组件 应用      更新时间:2023-09-26

我正在尝试做一个时钟组件,只是在网页中以本地格式给出日期和时间。我在我的webpack环境中使用命令行npm I moment--save导入了MomentJS。接下来,我在Clock.jsx组件中写了这篇文章(主要基于网站上的React示例)。

import React from 'react';
import Moment from 'moment';
export default class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dateTimestamp : Date.now()
    };
  }
  tick = () => {
    this.setState({dateTimestamp: this.state.dateTimestamp + 1});
    console.log('tick');
  }
  componentDidMount() {
    this.interval = setInterval(this.tick, 1000);
  }
  componentWillUnmount() {
    clearInterval(this.interval);
  }
  render() {
    const date = this.state.dateTimestamp;
    return(
      <div className="clock"> Heure locale : {date}</div>
    );
}
}

执行此操作时,时间戳正确递增。然而,当在对象中传递新的状态元素时,构造函数中会计算第一个值(基于Date.now()),但对于每个刻度,只有时间戳在递增,格式化的日期停留在其第一个值上。这是代码。

import React from 'react';
import Moment from 'moment';
export default class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dateTimestamp : Date.now(),
      dateFormatted : Moment(Date.now()).toString()
    };
  }
  tick = () => {
    this.setState({dateTimestamp: this.state.dateTimestamp + 1});
    console.log(this.state.dateTimestamp);
    this.setState({dateFormatted: Moment(this.state.dateTimestamp).toString()});
    console.log(this.state.dateFormatted);
  }
  ...
  render() {
    const date = this.state.dateFormatted;
    return(
      <div className="clock"> Heure locale : {date}</div>
    );
}
}

有人可以解释帮助我解决这个问题,但最重要的是告诉我我的代码出了什么问题吗?

感谢

最新消息:最后我对时间的使用是不合适的,即使我不明白为什么它不会以这种方式工作。请在下面找到我的正确实现,以便每隔几秒钟刷新一次日期和时间。

import React from 'react';
import Moment from 'moment';
export default class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dateFormatted : Moment().locale('fr').format('dddd Do MMMM YYYY HH:mm:ss').toString()
    };
  }
  tick = () => {
    this.setState({
      dateFormatted : Moment().locale('fr').format('dddd Do MMMM YYYY HH:mm:ss').toString()
    });
  }
  componentDidMount() {
    this.interval = setInterval(this.tick, 1000);
  }
  componentWillUnmount() {
    clearInterval(this.interval);
  }
  render() {
    const date = this.state.dateFormatted;
    return(
      <div className="clock"> Date (locale) : {date}</div>
    );
  }
}

这也"解决"了下面暴露的反模式问题(不同的交叉依赖setState()调用)。由于任何其他原因,我都需要时间戳,但我会找到一个变通方法。

@KrzysztofSztompka是正确的,但我要补充的是,维护两个单独的状态变量以将当前日期表示为数字和格式化字符串是一种反模式。派生的状态变量(即可以使用另一个状态变量计算的状态变量)增加了开发人员始终保持两个状态变量同步的责任。在这个简单的例子中,这似乎并不太困难,但在更大、更复杂的组件/应用程序中,这可能会变得更加困难。相反,通常认为更好的做法是保持一个真相来源,并根据需要随时计算任何派生值。以下是我如何将此模式应用于您的示例。

import React from 'react';
import Moment from 'moment';
export default class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dateTimestamp : Date.now()
    };
    this.tick = this.tick.bind(this);
  }
  tick() {
    this.setState({
      dateTimestamp: this.state.dateTimestamp + 1
    });
  }
  componentDidMount() {
    this.interval = setInterval(this.tick, 1000);
  }
  componentWillUnmount() {
    clearInterval(this.interval);
  }
  render() {
    // Calculate the formatted date on the fly
    const date = Moment(this.state.dateTimestamp).toString();
    return(
      <div className="clock"> Heure locale : {date}</div>
    );
  }
}

将勾选函数更改为:

tick = () => {
  var timestamp = this.state.dateTimestamp + 1;
  this.setState({
    dateTimestamp: timestamp,
    dateFormatted: Moment(timestamp).toString()
  });
}

这是因为从文档:

setState()不会立即更改this.state,而是创建挂起状态转换。调用this后访问this.state方法可能返回现有值。

因此,在您的下一个setState调用中,它使用旧值。我的主张同时改变了这两种价值观。