Skip to content

Instantly share code, notes, and snippets.

@townofdon
Last active March 3, 2019 23:55
Show Gist options
  • Save townofdon/5d05175ab103dfd0e0e6347fd65e71e6 to your computer and use it in GitHub Desktop.
Save townofdon/5d05175ab103dfd0e0e6347fd65e71e6 to your computer and use it in GitHub Desktop.
Autobind React Class Methods
import { Component } from 'react';
/**
* Auto-bind all methods of a React class, excluding lifecycle methods
*
* USAGE:
*
* ```
* class MyClass extends ComponentAutoBind { ... }
* ```
*/
class ComponentAutoBind extends Component {
constructor(props) {
super(props);
const prototype = Object.getPrototypeOf(this);
if (!prototype) { return this; }
if (typeof prototype !== 'object') { return this; }
const reservedFunctionNames = [
'constructor',
'getDerivedStateFromProps',
'shouldComponentUpdate',
'render',
'componentDidMount',
'componentDidUpdate',
'componentWillUnmount',
'setState',
];
const classPropertyNames = Object.getOwnPropertyNames(prototype);
classPropertyNames.forEach((propertyName) => {
if (reservedFunctionNames.includes(propertyName)) {
return;
}
if (!this[propertyName]) {
return;
}
if (typeof this[propertyName] !== 'function') {
return;
}
if (!prototype.hasOwnProperty(propertyName)) {
return;
}
this[propertyName] = this[propertyName].bind(this);
});
return this;
}
}
module.exports = ComponentAutoBind;
import React from 'react';
import ComponentAutoBind from './ComponentAutoBind';
class MyClass extends ComponentAutoBind {
constructor (props){
super(props);
this.state = {
a: 1,
b: 2,
c: 3,
};
// note the conspicuous absence of bindings here...
}
// this event handler will now be bound!
// best of both worlds - hot-reloading still works, and
// event handler is always bound.
_handleActionNumeroUno() {
console.log('UNO');
console.log(this.state);
}
// since this arrow function is transpiled as a constructor
// method, this method is not set on the class prototype.
// see: https://www.reactjunkie.com/demistifying-es6-class-method-and-property-initializer-arrow-function
// note - class properties as arrow functions can cause performance issues
// note - there is a history of hot-reloading not working for arrow functions.
_handleActionNumeroDos = () => {
console.log('DOS');
console.log(this.state);
}
render() {
return (
<div>
<button
className="btn-primary"
onClick={this._handleActionNumeroUno}
type="button"
>
uno!!
</button>
<button
className="btn-primary"
onClick={this._handleActionNumeroDos}
type="button"
>
dos!!
</button>
</div>
);
}
}
module.exports = ComponentAutoBind;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment