React 0.13.x and Autobinding
If you’re using React 0.13's shiny new class syntax…
class MyComponent extends React.Component {
}
…remember, there is no auto-binding.
class MyComponent extends React.Component {
componentDidMount() {
// `this` won't be what you think it is
MyFluxStore.listen(this.onChange);
}
onChange(state) {
// this is not this :(
this.setState(state);
}
}
An easy way to fix this is to use Function#bind.
class MyComponent extends React.Component {
componentDidMount() {
// yay!
MyFluxStore.listen(this.onChange.bind(this));
}
onChange(state) {
this.setState(state);
}
}
But that leads to problems when you plan on cleaning up your stores.
class MyComponent extends React.Component {
componentDidMount() {
// yay!
MyFluxStore.listen(this.onChange.bind(this));
}
componentWillUnmount() {
// uh-oh.
MyFluxStore.unlisten(this.onChange.bind(this));
}
onChange(state) {
this.setState(state);
}
}
This is because a new, and different, function is created when you use Function#bind. The Store won’t be de-registered and you’ll be leaking memory in your application.
So what should you do?
Save a reference to the bound function in your constructor!
class MyComponent extends React.Component {
constructor() {
super();
this.onChange = this.onChange.bind(this);
}
componentDidMount() {
MyFluxStore.listen(this.onChange);
}
componentWillUnmount() {
MyFluxStore.unlisten(this.onChange);
}
onChange(state) {
this.setState(state);
}
}
or better yet…use something like AltContainer which handles listening to stores for you in an elegant way.