I have a React
module that works fine in ES5
. I am converting it to ES6
and using 6to5
for the conversion. Everything transpiles fine, but I get a runtime error when I am trying to set my props
. When I drop a debugger
and look at this
, I see that this
is the EventEmitter
and not the class. Here is my code:
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());
}
....
};
The place I am having the issue is in my changeView
function. When it is transpiled
down it looks like this:
_onChange: {
value: function _onChange() {
this.setProps(getAppointments());
},
writable: true,
configurable: true
}
Again, inside that function, this
is my EventEmitter
. What is the way to fix this?
this.setProps
is deprecated, use state for this. It'll give you this warning in 0.13:
Warning: setProps(...) is deprecated in plain JavaScript React classes.
Also es6 class methods aren't autobound, so you need to bind it manually. You can either use .bind(this)
, or use arrow functions. For external emitters you do need to keep a reference, though.
You can just get rid of _onChange:
this._calendarListener = e => this.setState({things: e});
CalendarStore.addChangeListener(this._calendarListener);
Or bind in the constructor:
constructor(props){
...
this._onClick = this._onClick.bind(this);
}
Don't forget to unbind the event in componentWillUnmount:
componentWillUnmount(){
CalendarStore.removeChangeListener(this._onClick);
// or
CalendarStore.removeChangeListener(this._calendarListener);
}
Adding event listeners should be done in componentDidMount, not componentWillMount. The constructor replaces componentWillMount in es6 classes.
This code is very bad... you're overriding the props react sets:
this.props = {
view: 'weeks'
}
Just replace all occurrences of 'props' with 'state' in your code, and all will be good. Also you probably want the store's initial state.
this.state = {
view: 'weeks',
things: CalendarStore.getAppts()
}
Also, createClass isn't going away any time soon, so feel free to continue using it. It's often simpler. Stores should generally be handled by mixins, which is trivial with createClass, but more difficult to do right in es6 classes. I have a small library for mixins with react and es6 classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With