L’un des plus gros challenges dans une application React est d’afficher des données de manière efficace et efficiente. Plus l’application grandit, plus il devient difficile d’orchestrer correctement tous les composants tout en évitant les re-rendus inutiles.Nous allons voir, au cours de cet article, les différents moyens de partager de l’information entre les composants d’une application React. Nous verrons aussi les pièges à éviter pour faciliter la gestion des états dans React.
UseState et prop-drilling
Le flux de données dans React est unidirectionnel. Cela signifie que les données circulent dans un seul sens : des composants parents vers les composants enfants. L’objectif est de favoriser une architecture de données propre et prévisible.
Les props permettent de transmettre des données des composants parents aux composants enfants. Elles sont en lecture seule dans le composant enfant, ce qui garantit que ce dernier ne peut pas modifier directement ces données.
Le « prop-drilling » désigne le processus de transmission des props à travers plusieurs couches de composants. Certains de ces composants n’utilisent pas directement ces données et ne font que les relayer à leurs propres composants enfants.
Cela peut entraîner des difficultés de débogage, des comportements inattendus, ainsi que des composants étroitement couplés et difficiles à réutiliser.
React Context
Les contextes React permettent à un composant parent de mettre certaines informations à disposition de n’importe quel composant de l’arborescence, quelle que soit sa profondeur. La donnée devient ainsi accessible sans avoir à la transmettre explicitement via des props, ce qui permet de résoudre le problème du prop-drilling.
Un composant « abonné » à un contexte (via le hook useContext) est automatiquement re-rendu lorsqu’une modification intervient dans ce dernier. Cependant, toute modification d’une partie du contexte entraîne le re-rendu de tous les composants abonnés.
On peut alors envisager de créer un contexte par type de donnée afin de les partager dans notre arbre de composants. Mais que se passe-t-il si l’on se retrouve avec 50 contextes différents ? On plonge alors dans l’enfer des contextes.
L’enfer des contextes React survient lorsque l’API Context est utilisée de manière excessive ou inappropriée. C’est comme si votre application devenait un puzzle à trop de couches, rendant l’ensemble difficile à suivre et à maintenir.
Imaginez une situation avec de nombreuses couches, chacune contenant des éléments différents, comme des états ou des fonctions. Cela devient un véritable fouillis, difficile à comprendre, à tester et à maintenir.
Stores Redux
Un store Redux est un emplacement qui contient toutes les données. A l’inverse des contextes React, nous n’avons besoin que d’un seul store, lequel peut être découpé en « slices » (morceaux). La modification d’une partie du store entraîne des re-rendus des composants abonnés à cette partie seulement.
Une mise à jour d’une partie du store est déclenchée depuis n’importe quelle partie de l’arbre des composants. Une action utilisateur est le plus souvent à l’origine du déclenchement. Dans la terminologie Redux, cela s’appelle « dispatch » d’actions.
L’action est envoyée aux « reducers ». Ce sont des fonctions pures qui permettent de modifier l’état. Par exemple, une action « increment » déclenchera la fonction qui incrémente un compteur. Une autre action « addOrder » déclenchera la fonction qui ajoute une commande dans notre liste de commandes, etc.
La fonction reducer est exécutée, puis la partie du store concernée est mise à jour. Finalement, les composants abonnées déclenchent un re-rendu.
Conclusion
Nous avons vu au cours de cet article différentes façons de maintenir des données pour optimiser la gestions des états dans React. Ils est possible de combiner ces trois concepts précédemment étudiés, mais il est nécessaire de savoir quand et comment les utiliser :
- Utilisez le prop-drilling lorsque vous souhaitez passer des données à des dumb-components. Ceux-ci se contenteront d’afficher les données passées en paramètres, sans les transmettre à nouveau à d’autres composants.
- Utilisez les contextes pour des données de haut niveau qui nécessitent un re-rendu global : gestion du thème, de la langue, des préférences utilisateur, de l’authentification, etc.
- Utilisez un store Redux pour gérer les données métier : liste d’utilisateurs, liste de factures, etc.