Переменные состояния экземпляра v в react.js

121

Что лучше в response.js: хранить ссылку на тайм-аут как переменную экземпляра (this.timeout) или переменную состояния (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); 
     }
    ...
})

или

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

оба этих подхода работают. Я просто хочу знать причины использовать одно вместо другого.

brendangibson
источник
13
Из документации : « НИКОГДА не изменяйте this.stateнапрямую, так как setState()последующий вызов может заменить сделанную вами мутацию. Относитесь к ней так, this.stateкак если бы она была неизменной».
Феликс Клинг
6
Совет: используйте автоматическую привязку React:this.timeout = setTimeout(this.openWidget, DELAY);
Дэвид Хеллсинг,
1
На что следует установить DELAY?
Justingordon

Ответы:

171

Я предлагаю хранить его в экземпляре, а не в своем state. Всякий раз, когда stateобновляется (что должно выполняться только так, setStateкак предлагается в комментарии), React вызывает renderи вносит любые необходимые изменения в реальную DOM.

Поскольку значение timeoutне влияет на рендеринг вашего компонента, он не должен находиться в state. Помещение его туда вызовет ненужные вызовы render.

Росс Аллен
источник
12

В дополнение к тому, что сказал @ssorallen, вы также должны не забыть обработать размонтирование компонента перед вызовом handleLeave.

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); 
     },
    ...
});
разбойник
источник