我正在使用React和Flux创建Mission Clock网络应用。
可以在这里找到代码:https://github.com/jcadam14/Flux-Mission-Clock
现在这是非常基础的,我是React和Flux的新手,距离我编写任何JavaScript已有很长时间了(从事单一Java应用程序业务已经太久了)。这是为了获得概念证明,因此我可以基于React / Flux进行设计。
基本概念是“下一次联系”计时器倒数,当它在完成前达到1分钟时,计数器的框会变成红色。然后,当NextContact计时器完成时,CurrentContact计时器启动,并且新的NextContact计时器应该启动。
一切正常,直到NextContact组件完成,并应使用新的NextContact更新。组件和样式中的文本会更新,但倒数计时不会开始计时。它保持新值,但不启动计时器。
每次由于其他原因而发生渲染时,NextContact组件都会以新的时间再次更新,但不会开始计数。
但是,如果我将任何更改保存在任何文件中(我使用的是Visual Studio Code,且module.hot处于 Activity 状态),则计数器将启动,并且实际上会在应有的位置进行计数。因此,似乎变化并没有完全像我期望的那样呈现出来。
我尝试使用forceUpdate,但是它什么也没做,并且我尝试了各种获取Counter组件的方法,但是没有任何效果。
任何帮助将不胜感激。我希望一旦了解了这一点,并能理解所有调度工作是如何工作的,那么应用程序的其余部分应该就位(计时器是应用程序的核心组件,其他一切都非常简单)。
编辑:我还尝试使用Countdown编写一个简单的计时器应用程序,但是这次使用Redux,并且发生了同样的事情。因此,我想问题可能是您如何迫使组件重新初始化自身?
谢谢!
杰森
最佳答案
好吧,我最终只写了自己的计数器,这是:
import React,{Component} from 'react';
const formatValues = ({days,hours,minutes,seconds}) =>
{
const hourString = ('0' + hours).slice(-2);
const minString = ('0'+ minutes).slice(-2);
const secString = ('0' + seconds).slice(-2);
return (days + ':' + hourString + ':' + minString + ':' + secString);
}
class MCCountdown extends Component
{
constructor(props)
{
super(props);
this.state = {
endDate:this.props.endDate,
countdown:'0:00:00:00',
secondRemaining:0,
id:0
}
this.initializeCountdown = this.initializeCountdown.bind(this);
this.tick = this.tick.bind(this);
}
componentDidUpdate(prevProps, prevState)
{
if(this.props.endDate !== prevProps.endDate)
{
clearInterval(prevState.id);
this.setState({endDate:this.props.endDate});
this.initializeCountdown();
}
}
componentDidMount()
{
this.initializeCountdown();
}
tick() {
const values = this.getTimeRemaining(this.state.endDate);
this.setState({countdown:formatValues(values),secondRemaining:values.secondsLeft});
if(values.secondsLeft <= 0)
{
clearInterval(this.state.id);
if(this.props.onComplete)
{
this.props.onComplete();
}
return;
}
else
{
if(this.props.onTick)
{
this.props.onTick(this.state.secondRemaining);
}
}
}
getTimeRemaining(endtime){
const total = Date.parse(endtime) - Date.parse(new Date());
const seconds = Math.floor( (total/1000) % 60 );
const minutes = Math.floor( (total/1000/60) % 60 );
const hours = Math.floor( (total/(1000*60*60)) % 24 );
const days = Math.floor( total/(1000*60*60*24) );
return {
secondsLeft: total,
days,
hours,
minutes,
seconds
};
}
initializeCountdown(){
const values = this.getTimeRemaining(this.state.endDate);
const id = setInterval(() => this.tick(),1000);
this.setState({id:id,countdown:formatValues(values),secondRemaining:values.secondsLeft});
}
render()
{
const {countdown} = this.state;
return(<div>{countdown}</div>);
}
}
export default MCCountdown
这成功了。似乎我尝试过的所有计时器/计数器都可能缺少那个componentDidUpdate()方法,因为一旦我将其添加到MCCountdown中,当在组件上设置新日期时,时钟就会重新启动。
不确定这是否可以漂亮,但可以,我现在对此感到非常高兴。