Autobinding des classes ES6 en React

10 juin 2016 / Marouen Mhiri / React

Aprés avoir lu pas mal de documentation concernant ce theme, je me suis rendu compte que coder sa propre solution pourrai être la meilleure alternative. Dans cet article je vais expliquer ma fonction, qui concerne à définir une composante qui nous sauvera beaucoup de temps :-).

La méthode suivante va définir une composante de base pour toutes les autres composantes (dans le cas où ces dernières l'étendent). Cette composante de base ajoute une methode utile pour pouvoir atteindre un bon comportement des autres composantes (e.g. auto binding des méthodes à 'this').

					
import React from 'react';

export default class BaseComponent extends React.Component {

	constructor(...args) {
		super(...args);
		this.bindAllMethods();
	}

	bindAllMethods() {
		const properties = Object.getOwnPropertyNames(Object.getPrototypeOf(this));
		properties
			.filter(prop => typeof this[prop] === 'function')
			.forEach(method => {
				this[method] = this[method].bind(this);
			});
	}

}
					
				

La méthode "bindAllMethods" va permettre de lier le context des méthodes actuelles à `this`. Ceci veut dire, on peut maintenant appeler n'importe quelle méthode de notre composante comme une callback-méthode du jsx (e.g. `onClick={this.foobar}`), car cette première méthode s'occupera de trouver le context correct des autres méthodes.

Attention: Cette fonction prend en complte seulement les méthodes au sein de la classe actuelle. Elle ne considère pas l'hiérarschie de la classe mais ça peut être implementé si on en aura besoin.

Alors, comment utiliser cette composante de base? Il fait tout simplement l'importer et étuliser l'extend pour qu'elle soit prise en considération:

					
import BaseComponent from 'path to your BaseComponent';

export default class ComponentName extends BaseComponent {

	static displayName = 'ComponentName';

	foobar() {
		// do some stuff... (e.g)
		$('body').toggleClass('menu-is-open');
		...
	}

	componentDidMount() { ... }

	render() {
		return(
			<div>
				<a onClick={this.foobar} className="btn btn-default"></a>
			</div>
		);
	}
}
					
				

Tags :

react