Alléger son code avec des sous composants - Formation Gutenberg - Capitaine WP

Formation « Créer des blocs avec Gutenberg »

Créer des sous-composants pour alléger son code

Lecture :7 minutes •0

Notre code a tendance à devenir de plus en plus lourd, nous allons donc le découper en plusieurs parties en créant des composants React. On va notamment placer le code de l’inspecteur et de la toolbar dans des fichiers séparés.

Dans le cours précédent notre code dans edit.js commençait à devenir assez lourd. Le but de ce cours va être de scinder notre code en plusieurs fichiers.

Dans ce cours on va utiliser l’exemple 14 : src/14-components/ qui est simplement la reprise du bloc des exemples précédents, mais que j’ai scindé en plusieurs composants :

Les différents fichiers de code source
L’organisation du code en composants

On a :

  • edit.js qui représente toujours le bloc dans l’éditeur ;
  • toolbar.js qui s’occupera seulement de la barre d’outils ;
  • settings.js qui s’occupera uniquement des réglages de notre inspecteur ;
  • block.js qui s’occupera du rendu du bloc dans l’éditeur.

Cette organisation est complètement arbitraire. A vous d’opter pour la configuration idéale en fonction du contexte.

Les avantages à utiliser des sous-composants

Il y a plusieurs avantages à scinder son code en sous-composants. Le plus évident étant que votre code s’en retrouvera plus léger, et donc plus lisible.

Cela permet également de bien isoler les différents « pôles » de votre composant. Je pense en premier lieu à la Toolbar, l’inspecteur ainsi que le bloc : dans les exemples précédents tout était écrit à la suite, désormais chacun isolera son code dans son propre composant, lui-même dans son propre fichier JS.

De plus il faut savoir qu’un composant peut gérer sa propre logique (traitement des données) avant de les renvoyer au parent, ça évite d’ajouter trop de fonctions au composant principal.

Votre fichier edit.js, sera donc allégé en terme d’imports. Chaque composant importera les composants nécessaires de @wordpress/block-editor@wordpress/components et autres.

Plus tard, on verra notamment avec le bloc Google Maps que c’est le composant Inspecteur qui s’occupe de la recherche d’adresse et la transformation en coordonnées GPS (via le géocodeur Google). Et du coup l’inspecteur ne renvoie que la coordonnée au composant parent.

Réutiliser ses sous-composants

Il vous arrivera également de faire un élément assez conséquent qui sera possible de réutiliser. On va d’ailleurs très bientôt voir un composant de recherche d’articles. Au lieu de laisser le code dans l’inspecteur, on créera un autre un sous-composant que l’on nommera <Search>.

Il sera alors réutilisable. Du coup il serait même intéressant de créer un dossier composant à la base du projet src/components pour le rendre disponible aux autre blocs.

Un composant réutilisé

Sur l’image ci-dessus on voit que c’est le même composant utilisé pour le choix d’un produit, d’un article ou pour trouver une adresse (bon en réalité, trouver l’adresse nécessite l’API Google Maps, donc du coup il vaut mieux faire un composant à part entière pour ce cas précis).

Enfin en suivant cette logique de composants, il sera même très facile de les réutiliser plus tard dans un autre projet ou site. C’est ce qui est vraiment intéressant avec React.

Déclarer un composant

On va commencer par voir comment déclarer un composant React. Pour cela on va regarder src/13-composants/toolbar.js :

JSX
src/14-component/toolbar.js

En premier lieu, on va devoir charger Component de @wordpress/element, c’est une fine surcouche Gutenberg du composant React basique.

Ensuite, il suffit de déclarer une classe avec le nom que l’on veut donner à notre composant, dans ce cas Toolbar. Cette classe se base sur le composant React de base, d’où le extends Component.

Conseil

Les noms de classes commencent toujours par une majuscule. Si le nom est composé de plusieurs mots, on met une majuscule à chaque début de mot. Il faut éviter les espaces, accents et autres caractères spéciaux.

À Éviter

Bien entendu, n’utilisez pas le même nom que les composants natifs déjà existants. Il y aurait alors conflit de nom mais seulement si vous appelez les deux en même temps via import. Mais même sans ça, j’évite de réutiliser les mêmes noms pour ne pas créer de confusions et je vous conseille de faire de même.

Comme d’habitude on retrouve la fonction render() qui nous permettra d’afficher notre HTML.

On va pouvoir rajouter autant de fonctions que l’on veut avant le render(), et React propose même des hooks qui vont se lancer automatiquement lorsque le composant va se mettre à jour.

Pour rappel une des particularités de React est d’être capable de gérer le cycle de vie des composants et de mettre à jour automatiquement l’affichage de ceux dont les données ont changé.

Pensez à jeter également un oeil à settings.js et block.js pour voir comment est organisé le code à l’intérieur.

Écriture alternative

Il se peut que vous voyez dans d’autres exemples une écriture légèrement différente :

JS

Dans ce cas l’export est écrit à la fin du code. C’est exactement la même chose donc peut importe l’écriture utilisée.

En fait je ne sais pas si vous vous en souvenez, mais on avait déjà fait un export pour notre pictogramme SVG personnalisé. On avait simplement exporté une constante au lieu d’une classe, mais sinon c’est le même principe !

D’ailleurs les développeurs de WordPress n’utilisent pas la classe pour gérer les composants, mais une simple fonction. C’est tout à fait suffisant au final :

JSX

J’ai pris cet exemple sur le répertoire Github de Gutenberg.

Il n’y a pas grande différence à notre niveau, j’ai choisi les classes mais c’est purement arbitraire. À vous de voir ce qui vous convient le mieux !

Appeler nos sous-composants React

Dans edit.js, il faut maintenant importer nos composants en début de fichier en utilisant l’instruction import. Pour cela on va indiquer le nom que l’on a donné à la classe (avec sa majuscule) suivi de from puis le nom de fichier dans lequel la trouver.

JSX
src/14-components/index.js

./ indique que l’on reste dans le dossier dans lequel on se trouve actuellement. Notez qu’il n’est pas nécessaire de mettre l’extension .js à la fin.

Et dans la fonction return() on peut désormais utiliser nos composants en les appelant comme une balise HTML :

JSX

Dans ce cas on a un bel allègement de notre code. On comprend tout de suite que l’on retourne notre Toolbar, nos réglages et notre bloc !

Par contre, on va devoir transmettre nos props aux composants, afin qu’ils puissent à leur tour utiliser les valeurs et les fonctions. Je pense notamment à setAttributes().

Pour transmettre tout cela, il suffit de faire comme tout composant HTML natif, c’est-à-dire écrire des attributs dans notre composant, et ça ressemble à ceci :

JSX

Mais c’est très redondant puisque les clés et les valeurs sont tout le temps les mêmes. Du coup il existe avec React une écriture simplifiée qui commence avec les 3 petits points : <Toolbar { ...props } />.

En soi, ce que je viens d’écrire fonctionne tout le temps, mais c’est très bourrin : on envoie absolument toutes les props du composant parent vers l’enfant. En général ce n’est pas nécessaire pour des questions de performances.

Si vous envoyiez une valeur inutile dans ce composant, il serait mis à jour quand cette valeur change, alors qu’il n’en n’aurait pas le besoin. Du coup mieux vaut ne transmettre que le strict nécessaire.

D’ailleurs, par curiosité j’ai ajouté un console.log(props) dans mon bloc et voici ce que j’ai obtenu :

Le log des props

On a pas mal de données intéressantes. Mais seulement une poignée d’entre elles le sera réellement pour nos sous-composants.

On va donc lister seulement les valeurs et les fonctions à envoyer, avec ... devant, et React fera l’assignation clé/valeur lui-même.

Envoi des props utiles au composant

C’est le moment idéal pour utiliser l’écriture déstructurée que l’on a vu dans le précédent cours :

JSX

Dans ce cas précis je l’ai fait en 2 fois : j’ai d’abord déstructuré les props pour avoir les attributes au complet, puis j’ai ensuite déstructuré attributes pour avoir chaque valeur indépendamment.

  • Dans la Toolbar j’envoie setAttributes et l’alignement seulement ;
  • Dans l’inspecteur j’envoie chapterSign, textColor, withRadius, radius et également setAttributes ;
  • Et dans le bloc j’envoie className, setAttributes, et tous les attributs d’un coup.

Concernant le bloc, on a en effet besoin de tous nos attributs, puisque en théorie on va tous les utiliser. On a également besoin du setAttributes car c’est dans le bloc que l’on édite directement number et title, via les RichText.

C’est pour ça que j’ai d’un côté extrait de props attributes, et ensuite j’en ai fait une version décomposée. J’aurais pu sinon tout décomposer d’un coup et envoyer toutes les valeurs en les listant, mais ça fait long et peu élégant.

Récupérer les props dans le sous-composant

On va maintenant s’attarder sur nos sous-composants. Tout ce que l’on récupère du parent (qui cette fois n’est pas Gutenberg, mais notre bloc) sont des props.

Je peux donc à nouveau faire un petit coup d’assignation destructurée :

JSX
block.js

Exceptionnellement pour le composant Block, comme j’ai transmis directement attributes, un objet composé de sous-objets, je dois le double déstructurer pour taper title au lieu de attributes.title.

Warning

N’oubliez pas de bien mettre à jour les déstructurations de partout lorsque vous modifiez ou ajoutez un attribut dans votre bloc. Sinon vous aurez une erreur de valeur non déclarée.

Le mot-clé this

Tiens d’ailleurs, maintenant que l’on est dans un composant React de base, qui est une classe (donc de la POO) il faut utiliser le mot clé this quand on fait référence aux props : this.props, c’est-à-dire les props de cette instance de l’objet.

C’est pour ça que je destructure à partir de this.props et pas juste props. D’ailleurs, si vous ne déstructurez pas, il faudra alors utiliser quelque chose comme  this.props.attributes.radius.

Je vous conseille donc de déstructurer pour éviter les longueurs dans les noms de variables !

Il faudra utiliser this.maFonction() lorsque vous créerez des fonctions, mais on y reviendra.

Composant inception

Et du coup, maintenant que vous savez faire des composants, n’hésitez pas à organiser votre code en entités réutilisables. Vous pouvez même appeler des sous-sous-composants et créer autant de niveaux que nécessaire.

Il faut simplement à chaque fois passer les bonnes props et le tour est joué.

Et comme je le disais plus haut, si vous réalisez un composant qui aura son utilité ailleurs, placez-le en dehors du dossier du bloc. Gardez à l’esprit que React est fait pour créer des composants faciles à réutiliser dans d’autres blocs et projets.


Avec la connaissance de l’assignation destructurée et la création de composants, vous êtes maintenant parés pour créer des blocs toujours plus complexes mais qui gardent heureusement un code clair et organisé.

Il est maintenant temps de vous mettre à l’épreuve avec un nouveau devoir, avant d’attaquer les blocs dynamiques.

0

Questions, réponses et commentaires

Laisser un commentaire