Cet article est une version détaillée d'une réponse que j'ai faite à un collègue qui demandait si on avait des conseils ou des ressources pour commencer avec React aujourd'hui.
Ce qui suit est sans doute biaisé par mon expérience, ma vision des choses, ce qui pour moi est une bonne/mauvaise pratique, etc. Je partage tout ça ici pour aider certains qui pourraient être tentés de (re)mettre le nez dans React en 2021.
Le CRA tu éviteras !
Pour tout dire j'ai commencé React sans CLI. Très vite, comme je viens du monde Angular j'ai voulu utiliser CRA (Create React App) qui se dégageait comme l'équivalent du Angular CLI. Dans la pratique, après plus de 2 ans à l'utiliser, je ne peux que déconseiller CRA aujourd'hui.
L'outil évolue relativement lentement. On a pour ainsi dire pas du tout la main sur la moindre configuration, ce qui peut très vite devenir pénible dès qu'on veut quelque chose qui n'est pas parfaitement dans les clous. En fait si on veut faire simple : le CRA est configuré comme si vous vouliez créer une application React chez Facebook (React et CRA sont développés chez Facebook), or il y a peu de chance que vous bossiez chez Facebook, donc ne vous limitez pas à leur point de vue.
De mon côté je vous conseille de passer par ViteJS. Je l'ai testé côté pro avec React, je l'ai aussi testé en perso avec Lit. C'est une alternative aux outils de builds habituels, on peut en générer un projet en moins d'une seconde (sans exagérer), on a la main sur la configuration, même si par défaut tout va compiler pour la production et être servi en mode développement sans prise de tête. Avantage et inconvénient : vous devrez choisir un framework de test pour faire des tests unitaires, car rien n'est fourni de base. Les quelques minutes de configuration des tests seront par contre largement compensés par le fait qu'avec ViteJS toutes les compilations en mode développement sont instantanés, rafraîchissement dans le navigateur compris.
Des tests tu feras ! Mais sans Jest
En disant ça je sais que tout le monde ne sera pas d'accord avec moi, peut-être à raison. Mais même si Jest s'intègre très facilement à un projet JavaScript. Je ne trouve pas qu'il s'agisse d'un bon framework de test.
Pour commencer c'est un outil qui ne fonctionne pas très bien sous Windows. Jest est développé par Facebook, chez Facebook, les gens bossent sous macOS, donc c'est optimisé pour macOS (et plus largement les unix/linux). Sous Windows l'exécution est vraiment plus lente (j'ai un projet pro avec 900 tests qui mettent 1min20 à s'exécuter sur la CI sous Linux, alors que sur mon poste qui est plus puissant que la CI, il me faut pratiquement 5min pour exécuter tous les tests, avec un temps d'attente au démarrage des tests qui oscille entre 20 et 30 secondes).
Jest utilise aussi massivement JSDom. JSDom est une réimplémentation partiel d'un contexte de DOM qui est capable d'être exécuté en NodeJS. C'est une bonne idée en soit, pourquoi pas. Mais tout ça a un coût : on a pas toujours le même comportement entre JSDom et un navigateur, tout le contexte n'est pas présent, donc on peut très vite avoir l'impression de mocker toute l'API navigateur. JSDom est aussi plutôt lent.
Dans l'idée je sais que vous serez tentés d'utiliser Jest. Et clairement vous avez raison : c'est facile à installer, c'est la norme aujourd'hui d'utiliser Jest (mais ça ne veut rien dire, les modes ça passe).
Si des fois vous voulez tenter autre chose que Jest, je vous conseille de jeter un œil à Ava. C'est un autre framework de test, qui lui est extrêmement rapide, de l'ordre de la centième de seconde pour exécuter un test. L'API est très minimaliste mais très clair et très permissive.
Les snapshots tu baniras
Même si beaucoup de gens trouvent les snapshots merveilleux, je vous conseille de les fuir autant que possible.
Les snapshots ne sont pas des tests fiables : c'est lent, les toujours très mal utilisés, on ne regarde jamais vraiment ce qui change, les tests de snapshot sont toujours cassés sur une application en construction, on se retrouve très vite à cacher des erreurs, très souvent c'est un bon moyen de faire semblant de tester alors qu'on a été trop fainéant pour écrire un vrai TU qui teste vraiment quelque chose (et pourtant la couverture de code va être excellente).
D'expérience, et j'ai pourtant travaillé avec des gens qui étaient convaincus de l'utilité des snapshots, c'est un outil qui tend à rendre intestable une bonne partie de votre application.
Enzyme tu fuiras
Pour faire des tests composants en React, on trouve beaucoup de documentation autour d'Enzyme. Ça n'aurait pas été le cas il y a 2 ans, mais aujourd'hui je vous conseille de fuir cet outil au profil de Testing Library. C'est un framework de test composant qui vise à être compatible avec le plus de framework possible. On va pouvoir monter nos composants React dans un DOM virtuel (JSDom, mais avec Enzyme c'est le même combat) et interagir avec notre composant pour valider qu'il a bien le comportement attendu.
J'aime vraiment l'approche de Testing Library de se baser très fortement sur l'arbre d'accessibilité pour naviguer dans le DOM, j'aime aussi le fait qu'on manipule du DOM et non des composants, on est donc assez proche de ce que fait un utilisateur dans la vraie vie.
En parallèle, comme Testing Library dépend moins de comment fonctionne React, cette librairie n'est pas du tout un frein à la monté de version de React. Là où j'ai eu des mauvaises surprises avec Enzyme…
Adieu les class component
Même si on en trouve encore un peu dans la documentation, qu'il reste beaucoup de bibliothèques qui en utilisent, que l'équipe React a dit que les class component n'étaient pas à remplacer forcément par des function component il y a 2 ans et demi au moment de la sortie de React 16 ; je ne peux que constaté que les class component font partie du legacy de React, que c'est beaucoup moins pratique et expressif que les functions components, et que tout l'écosystème s'articule autour des function components.
Au fil des versions de React, on voit même des méthodes des class components qui sont dépréciés, on nous encourage à ne plus du tout utiliser certaines parties très importantes du cycle de vie des class component, alors que tout fonctionne parfaitement en function component.
Il reste sans doute quelques cas à la marge où les class component sont la bonne solution technique, mais après 2 ans et demi à faire du React, les function components ont convenu à remplir 99.9% de mes besoins.
Les hooks tu maîtriseras
Les functions components ont très vite été suivis d'une nouvelle API permettant de recréer tout le cycle de vie des class component, tout en offrant beaucoup plus de souplesse et d'expressivité. Cette API est l'API Hooks.
De la même façon que les class components sont devenus des fonctions component, les méthodes des class component sont devenus des appels à des fonctions parfaitement composables pour créer des fonctionnalités métier. On les reconnaît au nom, toutes ces fonctions commencent par use (comme useState, useRef, useEffect, useMemo, etc.), et on doit aussi par convention appeler nos customs hooks en les préfixant par use (comme useUserAccessRight).
Les hooks peuvent paraître très simpliste ou très complexe au début (ça dépend de vos expériences et votre manière de penser), mais c'est un point clé pour être capable de faire du code React propre aujourd'hui. En particulier la possibilité de créer des custom hooks, qui n'est pas encore assez utilisé à mon goût.
En plus d'améliorer la lisibilité de vote code, vous verrez que les custom hooks sont aussi beaucoup plus simple à maintenir et tester !
Du routing tu feras
La base du routing en React c'est react-router-dom. Il y a d'autres possibilités, mais cette bibliothèque fera parfaitement le travail dans la très vaste majorité des cas.
Il faut par contre faire attention à bien utiliser BrowserRouter, pour avoir des URL propre, ne pas avoir de # qui se promène dans l'URL et pour profiter d'une navigation avec un historique géré par le navigateur (on peut donc faire précédent/suivant comme pour un site qui ne serait pas une SPA).
Redux tu utiliseras
Je vois une tendance qui se renforce de ne plus utiliser Redux dans les projets React. Je comprends pourquoi, car c'est une brique encore à ajouter aux projets, on a beaucoup moins besoin de Redux pour créer une application React qu’auparavant avec l'API Hooks, mais je vous conseille quand même de garder Redux.
Redux vous impose une certaine organisation de votre projet. Vous pourrez beaucoup plus simplement séparer le métier de votre application et l'affichage. De plus le fait que Redux permettent d'utiliser les extensions (comme Redux DevTools) pour explorer l'état actuel de votre application, va vous aider fortement à maintenir l'application et comprendre les bugs qui se produiront. En parallèle utiliser Redux rend les composants beaucoup plus simple, léger et c'est assez naturel comme découpage.
Dans le même temps si vous vous dites "mon application est petite, je n'ai pas besoin de Redux", dites vous que les quelques minutes que vous perdrez à installer Redux, vous éviteront sans doute des heures de debug à l'aveugle dans quelques jours/semaines quand vous aurez fait une erreur quelque part qui vous n'arriverez pas à comprendre.
Si vous décidez de partir sur Redux, je vous conseille de faire le choix de Redux Toolkit, la nouvelle manière de faire de Redux. C'est ni plus ni moins qu'une petite surcouche qui va vous prémâcher la plupart des configuration et boilerplate de Redux.
Évidemment, je vous conseille d'ajouter react-redux qui va vous facilité la vie dans l'utilisation de Redux avec React. En particulier les hooks qui sont proposés par React-redux qui donne un accès très simple à l'état du store et au dispatch des action, avec pour ainsi dire plus aucun boilerplate !
Les Contextes, tu n'oubliras pas
En React on pense souvent components et propriétés, mais on pense rarement aux contextes. Les contextes permettent pourtant de très facilement partager des données entre différents composants d'une même grappe. C'est très pratique à utiliser et ça évite beaucoup de passage de propriétés.
Sans en utiliser partout, je pense que c'est important de comprendre comment fonctionnent les contextes pour pouvoir les utiliser quand on sent qu'on a un besoin de partager des données entre trop de composants.
L'architecture, tu n'improviseras pas
Un des grands problème pour moi de React c'est l'architecture. On a pas de vrai architecture de projet de référence. On fait donc ce qu'on veut, ou ce qu'on peut…
Je pense qu'un bon choix c'est de regarder du côté d'Angular ou de NextJS. Dans les deux cas on aura un découpage qui tente d'être clair, maintenable et scallable (au sens où ça reste maintenable et clair sur une grosse application).
Au style tu prendras garde
Pour la partie style (et donc CSS) il y a 3 grandes écoles : CSS, CSS modules, styled component.
Le style avec purement des CSS qu'on importe fonctionne très bien. Il faut faire attention au fait que le style à beau être dans plein de fichier à la fin tout se retrouve dans l'espace global et donc on peut créer des bugs de style par accident.
Les CSS modules ont comme promesse une encapsulation et un cloisonnement assez fort. C'est plutôt vrai et plutôt pratique de ce point de vue. Par contre ce n'est pas très souple et on manque parfois de la possibilité qu'on aurait en Angular par exemple de demander à avoir une règle de style qui s'applique à tous les enfants, sans polluer l'espace global.
Les styled components sont assez souples. On retrouve un cloisonnement assez fort, mais on a parfois du mal à cibler correctement nos éléments, du fait qu'on doive surcharger des éléments DOM par des styled components.
Je pense qu'il n'y a pas de solution idéale, il faut voir en fonction du besoin du projet et tester ce qui nous convient le mieux.
Des wrapper bootstrap tu te méfieras
Vous allez me dire "Non mais bootstrap, c'est fini, maintenant on fait tous XXX", eh bien dans le monde professionnel c'est encore très présent, et je pense que ce n'est pas près de changer.
Bootstrap et React ce n'est vraiment pas du tout un problème. Sauf pour ce qui est des composants bootstrap avec un comportement JS. Là on se retrouve parfois à devoir réécrire ce comportement en React.
Pour éviter ça, on trouve plusieurs bibliothèques React qui fournissent des composants wrapper pour les class Bootstrap. Entre autres : Reactstrap et React-Bootstrap. Dans tous les cas je vous conseille de ne pas utiliser trop ces wrapper qui peuvent alourdir le DOM final et compliqué à customisation du style. Personnellement j'ai tendance à n'utiliser que les composants qui nécessitent un comportement Javascript et pas les composants très simple comme les boutons.
TypeScript tu n'oublieras pas
Je sais que beaucoup ne seront pas de cet avis. Je suis le premier à me plaindre que les fichiers de typage sont parfois vraiment pas pratiques avec React. Il n'empêche que TypeScript permet de travailler avec un copilote en la personne du compilateur. On va prendre un peu de temps à typer tous nos modèles, nos propriétés, etc. Mais on va y gagner sur la durée, car on comprend plus facilement ce qu'on manipule, on a beaucoup plus d'aide des IDE, on a un filet de sécurité pour les casses de modèle.
Aujourd'hui je ne peux plus travailler efficacement sans TypeScript.
Conclusion
Si vous êtes passés à côté de React ou que vous êtes passé à autre chose pour diverses raisons, ça peut être un bon moment pour s'y (re)mettre. J'ai beau préférer d'autres solutions à React dans l'absolu, l'approche de React est très intéressante, et la communauté est plutôt productive en termes d'article, de documentation ou de bibliothèque.
En tout cas, si vous passez par là, merci à Gérôme pour ta question qui a conduit à cet article, et merci à Hoani qui m'a soufflé l'idée de transformer ce long message dans une conversation privée en article 👌