Instanz v Zustandsvariablen in react.js

121

Ist es in react.js besser, eine Timeout-Referenz als Instanzvariable (this.timeout) oder als Statusvariable (this.state.timeout) zu speichern?

React.createClass({
     handleEnter: function () {
         // Open a new one after a delay
         var self = this;
         this.timeout = setTimeout(function () {
             self.openWidget();
         }, DELAY);
     },
     handleLeave: function () {
        // Clear the timeout for opening the widget
        clearTimeout(this.timeout); 
     }
    ...
})

oder

React.createClass({
     handleEnter: function () {
         // Open a new one after a delay
         var self = this;
         this.state.timeout = setTimeout(function () {
             self.openWidget();
         }, DELAY);
     },
     handleLeave: function () {
        // Clear the timeout for opening the widget
        clearTimeout(this.state.timeout); 
     }
    ...
})

Beide Ansätze funktionieren. Ich möchte nur die Gründe für die Verwendung übereinander kennen.

brendangibson
quelle
13
Aus der Dokumentation : " NIEMALSthis.state direkt mutieren , da ein späterer Aufruf setState()die von Ihnen vorgenommene Mutation ersetzen kann. Behandeln Sie sie so, this.stateals ob sie unveränderlich wäre."
Felix Kling
6
Tipp: Verwenden Sie Reacts Autobindung:this.timeout = setTimeout(this.openWidget, DELAY);
David Hellsing
1
Auf was sollte DELAY eingestellt sein?
Justingordon

Antworten:

170

Ich schlage vor, es auf der Instanz zu speichern, aber nicht in seiner state. Bei jeder stateAktualisierung (die nur setStatewie in einem Kommentar vorgeschlagen durchgeführt werden sollte) ruft React auf renderund nimmt die erforderlichen Änderungen am realen DOM vor.

Da der Wert von timeoutkeinen Einfluss auf das Rendering Ihrer Komponente hat, sollte sie nicht verwendet werden state. Wenn Sie es dort ablegen, würde dies zu unnötigen Anrufen führen render.

Ross Allen
quelle
12

Zusätzlich zu den Aussagen von @ssorallen sollten Sie auch daran denken, das Aufheben der Bereitstellung der Komponente zu behandeln, bevor Ihr handleLeave aufgerufen wird.

React.createClass({
     handleEnter: function () {
         // Open a new one after a delay
         this._timeout = setTimeout(function () {
             this.openWidget();
         }.bind(this), DELAY);
     },
     handleLeave: function () {
        // Clear the timeout for opening the widget
        clearTimeout(this._timeout); 
     },
     componentWillUnmount: function(){
        // Clear the timeout when the component unmounts
        clearTimeout(this._timeout); 
     },
    ...
});
Räuber
quelle