2015-02-05 1 views
7

У меня есть модуль React, который отлично работает в ES5. Я конвертирую его в ES6 и используя 6to5 для преобразования. Все отлично переносится, но я получаю ошибку во время выполнения, когда пытаюсь установить props. Когда я бросаю debugger и смотрю this, я вижу, что this - это EventEmitter, а не класс. Вот мой код:Как разрешить `this` при преобразовании модуля React в класс ES6

var React = require('react'); 

import CalendarStore from './../stores/calendar.store.js'; 

function getAppointments() { 
    return {appts: CalendarStore.getAppts()} 
} 

export default class extends React.Component{ 
    constructor(props) { 
    super(props); 
    this.props = { 
     view: 'weeks' 
    } 
    } 

    changeView(child, view) { 
    this.setProps({view: view}); 
    } 

    componentWillMount() { 
    CalendarStore.addChangeListener(this._onChange); 
    } 

    _onChange() { 
    this.setProps(getAppointments()); 
    } 

    .... 
}; 

место я имею вопрос в моей changeView функции. Когда он transpiled вниз это выглядит следующим образом:

_onChange: { 
     value: function _onChange() { 
     this.setProps(getAppointments()); 
     }, 
     writable: true, 
     configurable: true 
    } 

Опять же, внутри этой функции, this мой EventEmitter. Каков способ исправить это?

ответ

16

this.setProps устарел, используйте состояние для этого. Это даст вам это предупреждение в 0.13:

Предупреждение: setProps (...) устарел в простых классах JavaScript для реагирования.

Также методы класса es6 не являются автономными, поэтому вам необходимо связать их вручную. Вы можете использовать .bind(this) или использовать функции стрелок. Тем не менее, для внешних излучателей вам нужно сохранить ссылку.

Вы можете просто избавиться от _onChange:

this._calendarListener = e => this.setState({things: e}); 
CalendarStore.addChangeListener(this._calendarListener); 

или связывать в конструкторе:

constructor(props){ 
    ... 
    this._onClick = this._onClick.bind(this); 
} 

Не забудьте отвязать событие в componentWillUnmount:

componentWillUnmount(){ 
    CalendarStore.removeChangeListener(this._onClick); 
    // or 
    CalendarStore.removeChangeListener(this._calendarListener); 
} 

Добавление прослушивателей событий должно выполняться в компонентеDidMount, а не в компонентеWillMount. Конструктор заменяет componentWillMount в классах es6.

Этот код очень плохо ... вы перекрывая реквизита реагируют наборы:

this.props = { 
    view: 'weeks' 
} 

Просто замените все вхождения «реквизита» с «состоянием» в вашем коде, и все будет хорошо. Также вы, вероятно, хотите начальное состояние магазина.

this.state = { 
    view: 'weeks', 
    things: CalendarStore.getAppts() 
} 

Кроме того, createClass не собирается уходить в ближайшее время, так что не стесняйтесь продолжать использовать его. Это часто проще. Магазины, как правило, обрабатываются mixins, что тривиально с createClass, но сложнее сделать это правильно в классах es6. У меня небольшая библиотека для mixins with react and es6 classes.

+0

Можете ли вы показать мне блог или где-нибудь, что объясняет, как магазины должны обрабатываться mixins? – jhamm

+0

Большинство реализаций потока обеспечивают одно. Mixin обрабатывает получение начального состояния из магазина, прослушивание магазина и выполнение this.setState при изменении. Он также очищает слушателя, когда компонент размонтирован. Вот пример [fluxxor store mixin] (http://fluxxor.com/documentation/store-watch-mixin.html) – FakeRainBrigand

+0

@FakeRainBrigand, если я также использую поток и устанавливаю значение по умолчанию, как это? '_handleStoreChange = (state: Object = {}) => {..}' Я получаю синтаксическую ошибку с babel 'Assigning to rvalue' – tsm