我正在使用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中,当在组件上设置新日期时,时钟就会重新启动。

不确定这是否可以漂亮,但可以,我现在对此感到非常高兴。

09-12 20:20