Photo by Tim Boote on Unsplash

Getting out of a .bind()

Thanks to class properties, never bind “this” to methods in class constructors again. 🎉

paul christophe
Frontend Weekly
Published in
2 min readOct 3, 2017

--

The Short

Instead of this:

class MyClass extends React.PureComponent {
constructor() {
this.myFunction = this.myFunction.bind(this);
}
myFunction() {
const { myVar } = this.props;
}


... etc
}

With class properties enabled in Babel, bound class methods are simple:

class MyClass extends React.PureComponent {
myFunction = () => {
const { myVar } = this.props;
}


... etc
}

The Long

When people start out with React they might create a simple increment counter demo:

Everything renders correctly on load and render is referencing this.state.count as expected. However, after clicking the “increment” button you’ll see the increment method throw an error:

Cannot read property 'state' of undefined

Weird, why could ‘render’ access state but not ‘increment’?

Method’s are bound to the class instance’s this value, however browsers invoke event handlers with a different context.

To fix the problem, we write this unintuitive line of code:

constructor() {
super();
this.state = {
count: 0,
}
this.increment = this.increment.bind(this)
}

Gross.

Class Fields / Properties to the Rescue

Class Fields are a stage 3 proposal that you can use right now with Babel. They allow us to write the previous example like so:

You see how we’re using = to declare state and increment? With this proposal, these two class variables are declared in the context of the class instance, aka this.

Thus, the this.state = {} inside of the constructor method is analogous to state = {} outside of the method.

In the case of increment, we set an arrow function which inherits the lexical scope. Lexical scope? Put simply, it inherits from it’s outer context, which in this case is our component instance.

--

--