React 0.13.x and Autobinding

Josh Perez
1 min readMay 5, 2015

--

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.

--

--