2015-07-09 7 views
1

Я стараюсь понять, как this работает в классах ES6, что затрудняет создание приложений с любой консистенцией. Вот один пример моего замешательства в React классе:Объем `this` в классах ES6

class Class extends React.Component { 

    constructor() { 

     super(); 

     this.state = { 
      timeout: 0 
     } 
    } 

    componentWillMount() { 

     // Register with Flux store. 
     // On change run this._storeUpdated() 
    } 

    _storeUpdated() { 

     if (this.state.timeout < 3) { 
      console.log(this.state.timeout); // 0 
      setTimeout(() => { 
       this.setState({ 
        authorized: false, 
        timeout: this.state.timeout + 1 // undefined? 
       }); 
       // Force Flux store to update - re-runs this method. 
      }, 1000) 
     } 
    } 
} 

Почему this.state.timeout undefined в вызове setState()? Однако, если я стрелка функционировать метод, то он работает:

_storeUpdated =() => { 

    if (this.state.timeout < 3) { 
     console.log(this.state.timeout); // 0 
     setTimeout(() => { 
      this.setState({ 
       authorized: false, 
       timeout: this.state.timeout + 1 // 1 
      }); 
      // Force Flux store to update - re-runs this method. 
     }, 1000) 
    } 
} 

Что на самом деле происходит?

+0

Как именно вы его вызываете? – zerkms

+0

Внутри компонентаWillMount –

+0

(с использованием Flummox) 'Flux.getStore ('store'). On ('change', this._storeUpdated);' –

ответ

3

Возможно, вы сбиты с толку, потому что React делает автообщение при использовании React.createClass, но это не происходит при наследовании от React.Component (т. Е. Путь ES6). Это изменение было объяснено в 0.13 beta1 blog post.

В вашем конкретном случае, и так как вы используете Flux.getStore('store').on('change', this._storeUpdated);, (который является method on EventEmitter3, а used by Flummox) контекст установлен на EventEmitter объект, который не имеет ничего общего с компонентом объекта и не имеет state атрибут.

Примечание Вы можете указать значение this в качестве третьего аргумента при регистрации слушателя событий: Flux.getStore('store').on('change', this._storeUpdated, <this-object>);

Для достижения autobind в классах ES6, вы должны использовать любой из методов, описанных в React блоге. В качестве побочного примечания, и если вы в ES7, вы можете даже использовать autobind decorator.

+1

'Вас может смутить, потому что React делает автообновление при использовании React.createClass' <, что именно оно. Этот ответ усиливает то, что сказали zerkms в чате. –