Instância v variáveis ​​de estado no react.js

121

No react.js, é melhor armazenar uma referência de tempo limite como uma variável de instância (this.timeout) ou uma variável de estado (this.state.timeout)?

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

ou

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

ambas as abordagens funcionam. Eu só quero saber as razões para usar um sobre o outro.

brendangibson
fonte
13
Na documentação : " NUNCA mude this.statediretamente, pois a chamada setState()posterior poderá substituir a mutação que você fez. Trate this.statecomo se fosse imutável."
Felix Kling
6
Dica: Use a ligação automática do React:this.timeout = setTimeout(this.openWidget, DELAY);
David Hellsing
1
O que DELAY deve ser definido?
justingordon

Respostas:

171

Sugiro armazená-lo na instância, mas não na sua state. Sempre que stateé atualizado (o que deve ser feito apenas setStateconforme sugerido em um comentário), o React chama rendere faz as alterações necessárias no DOM real.

Como o valor de timeoutnão tem efeito na renderização do seu componente, ele não deve residir state. Colocá-lo lá causaria chamadas desnecessárias para render.

Ross Allen
fonte
12

Além do que o @ssorallen disse, você também deve se lembrar de lidar com a desmontagem do componente antes que o handleLeave seja chamado.

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); 
     },
    ...
});
Brigand
fonte