2017-07-02 57 views
0

如何正确刷新moment.from()。我在componentDidMount中尝试set setInterval(this.renderReminders(),1000),但不起作用,弹出错误。如何解决这个问题?Rerender moment.fromNow()在React

class App extends Component { 
 

 
renderReminders() { 
 
    const { reminders } = this.props; 
 
    return (
 
     <ListGroup> 
 
     { 
 
      reminders.map(reminder => { 
 
      return (
 
       <ListGroupItem key={reminder.id}>    
 
       <div>{moment(reminder.dueDate, 'DD-MM-YYYY HH:mm').fromNow()}</div>    
 
       </ListGroupItem> 
 
      ) // return 
 
      }) // reminders.map 
 
     } 
 
     </ListGroup> 
 
    ) // return 
 
    } // renderReminders() 
 
    
 
    render() { 
 
    return (
 
     <div className="container">  
 
     { this.renderReminders() } 
 
     </div> 
 
    ) // return 
 
    } // render 
 
    
 
} // App

+0

你得到什么错误,当你把它放在componentDidMount? –

+0

看看这个类似的帖子与解决方案帮助:https://stackoverflow.com/questions/36299174/setinterval-in-a-react-app – terpinmd

回答

2

我想说有很多方法可以在React中制作计时器。
一个建议是推断提醒到另一个反应组件。

在新组件的状态中设置reminderTime,然后创建一个使用this.setState来更新计时器的方法。

如果状态发生变化,setState将自动重新渲染组件。

在componentWillMount中,您应该使用setInterval来调用将更新状态的函数。在componentWillUnmount中,您应该删除clearInterval的时间间隔。

我没有测试下面的代码,所以它主要是为了得到这个想法。

class Reminder extends React.Component{ 
 
    constructor(props){ 
 
     super(props); 
 
     this.state = { 
 
      reminderTime : moment(this.props.dueDate, 'DD-MM-YYYY HH:mm').fromNow()}, 
 
     } 
 
    } 
 

 
    componentDidMount(){ 
 
     // add the interval 
 
     this.interval = setInterval(this.updateReminderTime.bind(this), 3000); 
 
    } 
 

 
    componentWillUnmount(){ 
 
     // remove the interval listener 
 
     clearInterval(this.interval); 
 
    } 
 

 
    updateReminderTime(){ 
 
    this.setState({ 
 
     reminderTime : moment(this.props.dueDate, 'DD-MM-YYYY HH:mm').fromNow()} 
 
    } 
 
    
 
    render(){ 
 
     return <div>{this.state.reminderTime }</div> 
 
    } 
 
} 
 

 
class App extends Component { 
 
renderReminders() { 
 
    return (
 
     const reminders = this.props.reminders; 
 
     <ListGroup> 
 
     { 
 
      reminders.map(reminder => { 
 
      return (
 
       <ListGroupItem key={reminder.id}>    
 
       <Reminder dueDate={reminder.dueDate} />    
 
       </ListGroupItem> 
 
      ) // return 
 
      }) // reminders.map 
 
     } 
 
     </ListGroup> 
 
    ) // return 
 
    } // renderReminders() 
 
    
 
    render() { 
 
    return (
 
     <div className="container">  
 
     { this.renderReminders() } 
 
     </div> 
 
    ) // return 
 
    } // render 
 
    
 
} // App

+0

优秀的工作。 –

+0

我可以问一下吗?为什么你使用...绑定(这)...我百倍地阅读(与上下文有关的东西),虽然我无法正确理解它 –

1

而不是使用一个组件以使多个计时器的,我想你应该创建一个组件以使1个计时器,然后重新使用它为所有的情况下(通过定时器作为支持它)。

下面是一个基本的例子。

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {date: moment().format('DD-MM-YYYY HH:mm').fromNow()}; 
    } 

    componentDidMount() { 
    this.timerID = setInterval(
    () => this.tick(), 
     1000 
    ); 
    } 

    componentWillUnmount() { 
    clearInterval(this.timerID); 
    } 

    tick() { 
    this.setState({ 
     date: moment().format('DD-MM-YYYY HH:mm').fromNow() 
    }); 
    } 

    render() { 
    return (
     <div> 
     date={this.state.date} 
     </div> 
    ); 
    } 
} 

现在你只需要通过初始日期作为道具,并重新使用该组件为所有的定时器。

0

你应该保持剩余时间的状态,用setInterval来定期更新(递减)状态的那部分。然后这个状态更新将触发你的组件的渲染。

1

const {ListGroup, ListGroupItem} = Reactstrap; 
 

 
class App extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    
 
    this.state = { 
 
     interval: null, 
 
     reminders: this.nextReminders(props.reminders), 
 
    }; 
 
    
 
    this.refreshReminders = this.refreshReminders.bind(this); 
 
    this.nextReminders = this.nextReminders.bind(this); 
 
    } 
 
    
 
    componentDidMount() { 
 
    const interval = setInterval(this.refreshReminders, 1000); 
 
    this.setState({ interval }); 
 
    } 
 
    
 
    componentWillUnmount() { 
 
    const { interval } = this.state; 
 
    clearInterval(interval); 
 
    } 
 
    
 
    refreshReminders() { 
 
    const { reminders } = this.props; 
 
    const nextReminders = this.nextReminders(reminders); 
 
    
 
    this.setState({ reminders: nextReminders }); 
 
    
 
    console.log('refresh !'); 
 
    } 
 
    
 
    nextReminders(reminders) { 
 
    return reminders.map(reminder => { 
 
     return { 
 
     ...reminder, 
 
     render: moment(reminder.dueDate, 'DD-MM-YYYY HH:mm').fromNow() 
 
     }; 
 
    }); 
 
    } 
 
    
 
    renderReminders() { 
 
    const { reminders } = this.state; 
 
    
 
    return (
 
     <ListGroup> 
 
     { 
 
      reminders.map(reminder => { 
 
      return (
 
       <ListGroupItem key={reminder.id}>    
 
       <div>{reminder.render}</div>    
 
       </ListGroupItem> 
 
      ) // return 
 
      }) // reminders.map 
 
     } 
 
     </ListGroup> 
 
    ) // return 
 
    } // renderReminders() 
 
    
 
    render() { 
 
    return (
 
     <div className="container">  
 
     { this.renderReminders() } 
 
     </div> 
 
    ) // return 
 
    } // render 
 
    
 
} // App 
 
    
 
const data = [ 
 
    {id: 1, dueDate: '02-07-2017 15:34'}, 
 
    {id: 2, dueDate: '02-07-2017 13:00'}, 
 
    {id: 3, dueDate: '02-07-2017 14:00'}, 
 
]; 
 
    
 
ReactDOM.render(<App reminders={data} />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> 
 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://unpkg.com/reactstrap/dist/reactstrap.min.js"></script> 
 

 
<div id="app"></div>