2016-08-12 80 views
0

我使用moment.duration建立在react.js应用倒数计时器,从API调用在componentDidMount访问拉原倒数时间重新渲染分量。阵营与Moment.duration:当持续时间达到0

这很多工作正常 - 我想,一旦我的持续时间为0(一旦一个事件开始),重新渲染组件(这将反过来拉新的时间作为倒计时,作为json将会与即将开始的活动一起刷新)。

这似乎是它应该很容易与反应,因为我基本上要我每次到达时间,或当倒数时间重新呈现组件= 0

这里是我的代码的渲染部分:

render: function() { 
    UpcomingMenu = this.state.upcomingList || []; 
    var currentTime = Math.round(new Date().getTime()/1000); 
    // current system time in seconds 
    console.log(currentTime); 

    return (
     <div> 
     <span>Upcoming LIVE Event: </span> 
     {UpcomingMenu.map(function(el, i){ 

     if (el.eventStart > currentTime) { 
      while (i < 1) { //i hate while loops. find a better way... 
      var diffTime = el.eventStart - currentTime; 
      var duration = moment.duration(diffTime*1000, 'milliseconds'); 
      var interval = 1000; 
      if (typeof el.eventStart !== 'undefined') { //to prevent render twice error. i'm sure there's a better way around this. 
       setInterval(function(){ 
       duration = moment.duration(duration - interval, 'milliseconds'); 
        $('.countdown').text(duration.days() + "d " + duration.hours() + "h " + duration.minutes() + "m " + duration.seconds() + "s") 
       }, interval); 
      //re-render component? 
      }; 

      var eventDetailsURL = decodeURIComponent(el.eventDetailsURL); 
      var eventLiveURL = decodeURIComponent(el.eventLiveURL); 
       return <span key={i}> 
        <strong><a target="_blank" href={eventDetailsURL}>{el.eventTitle}</a></strong> 
        <p> 
        <span className="countdown"></span>      
        </p> 

       </span> 
      }; 

       };    
      })} 


      </div>   
    ); 
    } 
    }); 
+0

当持续时间为0时,刷新用更多的数据的状态。这将照顾重新渲染。 – vijayst

+0

@Vijay谢谢 - 是的,但是持续时间现在只在页面加载时设置。 – dilettante

+0

@dilettante在reactjs主页有一个基于定时器例如:https://facebook.github.io/react/index.html。如果你还没有,请看看它。基本上你想在那里做一些类似'打勾'的功能,并且适当地保持设置状态(或重置状态),这将负责重新渲染组件。 – KumarM

回答

0

将setInterval放入您的render()函数中并不是一个好习惯。渲染应该是纯粹的,没有副作用。您始终可以将间隔设置为另一种生命周期方法,例如。 componentDidMountcomponentWillReceiveProps

class Timer extends React.Component { 
    static propTypes = { 
    eventStartTime: React.PropTypes.Date.isRequired 
    }; 

    // every logic is here 
    updateTimer =() => { 
    // clean up previous timer 
    clearTimeout(this.timer); 

    const millisecondsAhead = this.props.eventStartTime - Date.now(); 
    const eventStarted = millisecondsAhead < 0; 

    // calling setState will make your component re-render 
    this.setState({ 
     eventStarted: eventStarted 
    }); 

    if (!eventStarted) { 
     this.timer = setTimeout(this.updateTimer, 1000); 
    } 
    } 

    constructor(props) { 
    this.state = { 
     eventStarted: false 
    }; 

    this.updateTimer(); 
    } 

    componentWillReceiveProps(nextProps) { 
    if (nextProps.eventStartTime !== this.props.eventStartTime) { 
     this.updateTimer(); 
    } 
    } 

    render() { 
    const { eventStarted } = this.state; 
    const millisecondsAhead = this.props.eventStartTime - Date.now(); 
    /* 
    * render according to eventStarted and millisecondsAhead 
    */ 
    } 
} 
+0

最好使用setInterval而不是setTimeout。也许,另一种称为initTimer的方法来执行清理操作并启动定时器。 – vijayst

+1

@tungv作为一个很好的做法你会希望有构造函数在类的第一件事。否则就会令人困惑。 – KumarM

+0

你好,setInterval大部分工作,并且我在类定义的早些时候移动了构造函数。感谢你们两位。 – dilettante