Ato*_*_84 5 javascript momentjs reactjs react-jsx
我正在尝试做一个时钟组件,只是在网页中以本地格式给出日期和时间.我在我的webpack环境中使用命令行npm i -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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
这样做时间戳正确递增.但是,在对象中传递新的state元素时,第一个值(基于Date.now())是在构造函数中计算的,但是对于每个tick,只有时间戳递增格式化的日期会粘贴在其第一个值上.这是代码.
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有人能解释帮助我解决这个问题,但最重要的是告诉我我的代码有什么问题?
谢谢
更新:最后我使用的时刻是不合适的,即使我无法弄清楚为什么它不会这样工作.在下面找到我正确的实现,以便每秒刷新日期和时间.
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
这也"解决"下面公开的反模式问题(不同的交叉相关的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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
将您的刻度函数更改为:
tick = () => {
var timestamp = this.state.dateTimestamp + 1;
this.setState({
dateTimestamp: timestamp,
dateFormatted: Moment(timestamp).toString()
});
}
Run Code Online (Sandbox Code Playgroud)
这是因为来自文档:
setState() 不会立即改变 this.state ,而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。
因此,在下一个 setState 中调用它时使用旧值。我的建议立即改变这两个值。
| 归档时间: |
|
| 查看次数: |
10550 次 |
| 最近记录: |