/ es6

It's the little things

Today I hit a small pain point while working in React and decided that enough was enough. It's one that anyone working with es6 and React will run into: binding your component methods.

class someComponent extends React.Component {
constructor(props) {
  super(props);

  this.someMethod = this.someMethod.bind(this);
  this.otherMethod = this.otherMethod.bind(this);
  ... preposterously long list of methods here

Sure it's a small thing but when I went to add another function to the growing list I decided that I should make a better way. So I did.

The Solution

It was actually quite easy to do although the implementation is a little naive. I simply made a function in my utils, so I can import it easily, which will bind the methods for any component for me. The function when called find the prototype of the component it is called on using getPrototypeOf and then gets and array of the properties on the prototype using getOwnPropertyNames. Finally it loops over each property and, for every property that is both a function and not a lifecycle hook, it binds that method to the component.

const proto = Object.getPrototypeOf(this);
const keys = Object.getOwnPropertyNames(proto);
keys.forEach((key) => {
  if (!methodsToSkip[key] && (typeof this[key] === 'function')) {
    this[key] = this[key].bind(this);
  }
}); 

I wrote it using this because it felt most natural. It does mean that you must call it in the components constructor with a .call or .apply

constructor(props) {
  super(props);

  methodBinder.call(this);
}

You could of course instead just pass this into the the function and refer to it as an argument in the function instead.

Now I said this is a bit naive because it does end up binding ALL of your methods when that technically isn't necessary. But the truth is that I have a habit of doing that manually anyways simply to prevent myself from forgetting. To my knowledge there is no real performance tradeoff. If you know otherwise however, please let me know!!

So there it is. Simple, easy and removes an annoying rote task. Five minutes well spent :)