2016-03-30 11 views
30

Ich bin immer noch relativ neu bei React, aber ich habe mich langsam weiterentwickelt und bin auf etwas gestoßen, auf dem ich feststecke.setInterval in einer React App

Ich versuche, eine "Timer" -Komponente in React zu bauen, und um ehrlich zu sein, weiß ich nicht, ob ich das richtig mache (oder effizient). In meinem Code unten, habe ich den Zustand eines Objekts { currentCount: 10 } zurückzukehren und liebäugelt wurden mit componentDidMount, componentWillUnmount und render und ich kann nur den Zustand bekommen zu „Countdown“ von 10 bis 9.

zweiteilige Frage : Was mache ich falsch? Und gibt es einen effizienteren Weg mit setTimeout (statt componentDidMount &)?

Vielen Dank im Voraus.

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 (diese)' nicht mehr benötigt wird, reagieren tut dies für sich allein jetzt. – Derek

+2

Ihre Timer-Methode aktualisiert currentCount nicht –

+1

@Derek sind Sie sicher? Ich habe gerade meine Arbeit, indem ich 'this.timer.bind (this)' hinzugefügt, da this.timer auf der eigenen nicht funktioniert –

Antwort

60

Ich sehe 4 Ausgaben mit Ihrem Code:

  • In Ihrem Timer-Methode werden Sie immer Ihre aktuelle Anzahl auf 10
  • Einstellung Sie versuchen, den Zustand in aktualisieren Methode machen
  • Sie Verwenden Sie die setState Methode nicht, um den Status zu ändern
  • Sie speichern Ihre intervalId nicht im Status

Lassen Sie uns versuchen, das zu beheben:

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> 
    ); 
} 

Diese in einem Timer führen würde, die -N von 10 abnimmt. Wenn Sie Timer möchten, die auf 0 abnimmt, können Sie leicht modifizierte Version verwenden:

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

Danke. Das macht sehr viel Sinn. Ich bin immer noch sehr viel Anfänger und ich versuche herauszufinden, wie State funktioniert und was in welchen "Chunks" rendern geht. – Jose

+0

Ich frage mich, ob es notwendig ist, componentDidMount und componentWillUnmount zu verwenden, um das Intervall tatsächlich festzulegen? EDIT: Nur Ihre letzte Bearbeitung gesehen. :) – Jose

+0

@Jose Ich denke, 'componentDidMount' ist der richtige Ort, um die clientseitigen Ereignisse auszulösen, also würde ich damit den Countdown einleiten. An welche andere Methode denken Sie zur Initialisierung? – dotnetom

10

Aktualisiert 10-Sekunden-Countdown mit 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;