2016-03-30 14 views
30

Sono ancora abbastanza nuovo in React, ma ho rallentato lentamente e ho incontrato qualcosa su cui sono bloccato.setInterval in una app React

Sto provando a costruire un componente "timer" in React e, sinceramente, non so se lo sto facendo correttamente (o in modo efficiente). Nel mio codice qui sotto, ho impostato lo stato per restituire un oggetto { currentCount: 10 } e hanno accarezzato componentDidMount, componentWillUnmount e render e posso ottenere solo lo Stato a "conto alla rovescia" da 10 a 9.

due parti domanda : Cosa sto sbagliando? E, c'è un modo più efficiente di usare setTimeout (piuttosto che usare componentDidMountcomponentWillUnmount)?

Grazie in anticipo.

import React from 'react'; 

var Clock = React.createClass({ 

    getInitialState: function() { 
    return { currentCount: 10 }; 
    }, 

    componentDidMount: function() { 
    this.countdown = setInterval(this.timer, 1000); 
    }, 

    componentWillUnmount: function() { 
    clearInterval(this.countdown); 
    }, 

    timer: function() { 
    this.setState({ currentCount: 10 }); 
    }, 

    render: function() { 
    var displayCount = this.state.currentCount--; 
    return (
     <section> 
     {displayCount} 
     </section> 
    ); 
    } 

}); 

module.exports = Clock; 
+2

'bind (questo)' non è più necessario, reagire fa questo da solo ora. – Derek

+2

il tuo metodo timer non aggiorna currentCount –

+1

@Derek sei sicuro? Ho appena ottenuto il mio lavoro aggiungendo 'this.timer.bind (this)' come questo.timer su di esso non ha funzionato –

risposta

60

vedo 4 problemi con il codice:

  • nel metodo timer si è sempre imposta il valore corrente al 10
  • Si tenta di aggiornare lo stato di render metodo
  • È non utilizzare il metodo setState per modificare effettivamente lo stato
  • Non si sta memorizzando l'intervalloId nello stato

Proviamo a riparare quello:

componentDidMount: function() { 
    var intervalId = setInterval(this.timer, 1000); 
    // store intervalId in the state so it can be accessed later: 
    this.setState({intervalId: intervalId}); 
}, 

componentWillUnmount: function() { 
    // use intervalId from the state to clear the interval 
    clearInterval(this.state.intervalId); 
}, 

timer: function() { 
    // setState method is used to update the state 
    this.setState({ currentCount: this.state.currentCount -1 }); 
}, 

render: function() { 
    // You do not need to decrease the value here 
    return (
     <section> 
     {this.state.currentCount} 
     </section> 
    ); 
} 

questo si tradurrebbe in un timer che diminuisce da 10 a -N. Se si desidera che il timer che scende a 0, è possibile utilizzare la versione leggermente modificata:

timer: function() { 
    var newCount = this.state.currentCount - 1; 
    if(newCount >= 0) { 
     this.setState({ currentCount: newCount }); 
    } else { 
     clearInterval(this.state.intervalId); 
    } 
}, 
+0

Grazie. Questo ha molto senso. Sono ancora un principiante e sto cercando di capire come funziona lo stato e cosa succede in "pezzi", come render. – Jose

+0

Mi chiedo, tuttavia, è necessario utilizzare componentDidMount e componentWillUnmount per impostare effettivamente l'intervallo? EDIT: hai appena visto la tua modifica più recente. :) – Jose

+0

@Jose Penso che 'componentDidMount' sia il posto giusto per attivare gli eventi lato client, quindi lo userei per avviare il conto alla rovescia. Quale altro metodo stai pensando di inizializzare? – dotnetom

10

Aggiornato 10 secondi del conto alla rovescia utilizzando class Clock extends Component

import React, { Component } from 'react'; 

class Clock extends Component { 
    constructor(props){ 
    super(props); 
    this.state = {currentCount: 10} 
    } 
    timer() { 
    this.setState({ 
     currentCount: this.state.currentCount - 1 
    }) 
    if(this.state.currentCount < 1) { 
     clearInterval(this.intervalId); 
    } 
    } 
    componentDidMount() { 
    this.intervalId = setInterval(this.timer.bind(this), 1000); 
    } 
    componentWillUnmount(){ 
    clearInterval(this.intervalId); 
    } 
    render() { 
    return(
     <div>{this.state.currentCount}</div> 
    ); 
    } 
} 

module.exports = Clock;