如何在将React模块转换为ES6类时解决`this`

jha*_*amm 7 ecmascript-6 reactjs

我有一个React工作正常的模块ES5.我正在将其转换为ES66to5用于转换.一切都很好,但是当我试图设置我的时候,我遇到了运行时错误props.当我放下debugger并观察时this,我看到的this是那EventEmitter不是阶级.这是我的代码:

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

  ....
};
Run Code Online (Sandbox Code Playgroud)

我遇到问题的地方在于我的changeView职能.当它transpiled关闭时它看起来像这样:

  _onChange: {
      value: function _onChange() {
        this.setProps(getAppointments());
      },
      writable: true,
      configurable: true
    }
Run Code Online (Sandbox Code Playgroud)

再次,在这个功能里面,this是我的EventEmitter.解决这个问题的方法是什么?

Bri*_*and 16

this.setProps不推荐使用,为此使用状态.它会在0.13中给你这个警告:

警告:在纯JavaScript React类中不推荐使用setProps(...).

此外,es6类方法不会自动响应,因此您需要手动绑定它.您可以使用.bind(this)或使用箭头功能.但是,对于外部发射器,您需要保留参考.

你可以摆脱_onChange:

this._calendarListener = e => this.setState({things: e});
CalendarStore.addChangeListener(this._calendarListener);
Run Code Online (Sandbox Code Playgroud)

或者在构造函数中绑定:

constructor(props){
   ...
   this._onClick = this._onClick.bind(this);
}
Run Code Online (Sandbox Code Playgroud)

不要忘记在componentWillUnmount中取消绑定事件:

componentWillUnmount(){
    CalendarStore.removeChangeListener(this._onClick);
    // or 
    CalendarStore.removeChangeListener(this._calendarListener);
}
Run Code Online (Sandbox Code Playgroud)

添加事件侦听器应该在componentDidMount中完成,而不是componentWillMount.构造函数替换es6类中的componentWillMount.

这段代码非常糟糕......你要重写道具反应集:

this.props = {
  view: 'weeks'
}
Run Code Online (Sandbox Code Playgroud)

只需在代码中用'state'替换所有出现的'props',一切都会好的.你也可能想要商店的初始状态.

this.state = {
  view: 'weeks',
  things: CalendarStore.getAppts()
}
Run Code Online (Sandbox Code Playgroud)

此外,createClass不会很快消失,所以请随时继续使用它.它通常更简单.商店通常应该由mixin处理,这对于createClass来说是微不足道的,但在es6类中更难做到.我有一个小型库,用于mixin和react和es6类.