Problème du this undefined dans un gestionnaire d’événement React

Cet article traite de l’objet this qui est indéfini dans une méthode de classe d’un composant React.

La crique Lulworth Cove sur le littoral du Dorset dans le sud de l'Angletterre, et les textes this et Uncaught TypeError: Cannot read …

Supposons avoir le code suivant pour une application :

Dans ce composant très simple, on accède à la méthode avec this.handleClick. Mais lorsqu’on lance l’application, et que l’on clique sur le bouton, on se retrouve avec la méchante erreur: Uncaught TypeError: Cannot read property 'state' of undefined.

Pourquoi ? Si l’on exécute en mode non strict, this se réfère à l’objet window, dans le cas du mode strict, il n’est pas défini. Comment contourner cela ? Il y a deux possibilités.

Option 1 : bind

Ce n’est pas la meilleure solution, mais on peut explicitement lié l’objet this à la méthode où l’on veut l’utiliser avec un bind :

En ajoutant cette ligne au constructeur du composant, this se réfère au composant dans la méthode gérant le click.

Ce n’est pas, à ce qu’il parait, terriblement performant. Imaginons avoir une dizaine de boutons sur la page. Cela signifie que l’on lie 10 instances de this à la fonction. Cela n’aura pas un gros impact sur notre exemple simple, mais l’on peut imaginer des composants bien plus complexes, et cela pourrait avoir plus d’influence sur la performance.

Option 2 : fonctions fléchées

Les fonctions fléchées ne se soucient pas du this. Lorsque l’on utilise des fonctions fléchées, le gestionnaire d’événement est lié à l’instance du composant, et l’on n’a pas besoin d’utiliser bind dans le constructeur.

Une autre façon d’appeler le gestionnaire d’événement est d’écrire la fonction fléchée dans l’attribut onClick du composant en appelant le gestionnaire, on peut passer l’événement comme argument :

Et hop, le gestionnaire d’événement a accès à l’objet this, qui n’est plus undefined.

Soumettre un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables.