Le bon moment pour transférer un state dans Redux

Paul-Yves Lucas
Captain Contrat Tech
4 min readMay 2, 2019

“Quand dois-je créer un reducer dans mon store Redux pour exposer un état partagé ?”. Si vous vous êtes déjà posé cette question, cet article est fait pour vous.

Tout d’abord, une compréhension basique de React et Redux est nécessaire. Je considère qu’on en est au point où on se demande si l’état d’un composant devrait être exposé par le store ou non.

Redux en deux mots : état partagé

Les bénéfices de Redux sont multiples, mais là n’est pas notre propos. Rappelons seulement ce qui nous intéresse : le fait que Redux fournisse un état (state) partagé dans lequel tous les composants qui le souhaitent peuvent extraire des informations à connecter à leur propres propriétés (props).

Cet état est le store. Il est composé par des reducers qui vont le modifier en fonction des actions diffusées par les composants.

Quand utiliser le store ?

Les personnes ayant travaillé sur des applications de taille moyenne avec React nous comprendront. Regrouper tous les états de tous les composants dans un store commun s’avère rapidement être une mauvaise idée (même si ce store est correctement divisé entre plusieurs fichiers). En effet, certains composants sont suffisamment indépendants, si bien qu’il n’y a finalement aucun bénéfice à partager leur état au regard de tous, ça ne rendrait les choses que plus complexes.

Mais alors, quand doit-on partager un état dans le store ?

Mon avis est le suivant : ce partage doit avoir lieu dès qu’un état est transmis comme props à d’autres composants de façon trop complexe, que ce soit pour des raisons de profondeur (on veut transmettre l’état à ses petits-enfants) ou de largeur (on utilise une prop et un callback pour la modifier afin de la partager aux composants frères). Un reducer peut aussi servir dans des cas particuliers tel qu’un besoin de contrôle externe, ce qui arrive quand on utilise des librairies externes non adaptées à React par exemple.

L’exemple de la barre de navigation

Prenons un exemple concret pour illustrer et clarifier mon propos : nous sommes en train d’ajouter une barre de navigation (navbar) dépliable à notre application.

Nous disposons donc d’un composant NavBar, avec un état qui contient le booléen displayed. La barre de navigation contient elle-même un bouton pour se replier mais au sein même du composant. On peut donc garder tout dans le composant NavBar sans soucis.

Pour pouvoir déplier la barre de navigation, il faut ajouter un bouton (OpenNavButton) à l’extérieur de celle-ci, mais qui va pouvoir agir sur son état. Nos deux composants ont heureusement un parent direct en commun. C’est donc ce parent qui va stocker un état displayNav (booléen) et le transmettre à ses enfants avec en prime une méthode de modification :

Jusqu’ici ça reste encore clair, la complexité est non nulle mais reste acceptable.

Mais que se passe-t-il si OpenNavButton n’est pas directement appelé par AppLayout, mais par un de ses enfants ?

Nous avons désormais de nombreux composants qui transmettent la fonction toggleNav dans leurs props pour leurs enfants, et ce dans l’unique finalité de la transmettre à OpenNavButton. Non seulement la complexité est assez grande, mais AppRouter et BusinessComponent n’ont pas du tout l’usage de toogleNav. Ils se contentent seulement de le transmettre sans vraiment savoir pourquoi. Travailler sur ces composants de façon indépendante (pour une autre raison que notre barre de navigation) va poser beaucoup d’interrogations sur ce sujet.

C’est alors le moment idéal de changer le code et y ajouter un reducer Redux afin d’exposer l’état de la barre de navigation ainsi qu’une action pour changer cet état. Lorsqu’au moins deux composants se contentent de transmettre des propriétés qu’on leur donne, sans en avoir un quelconque usage, il est alors temps de déplacer l’état à l’origine de ces props dans le store Redux.

Un retour à la simplicité 🎉

Migration progressive vers Redux

Pour finir, il ne faut pas oublier que cette méthode de décision n’est sûrement pas la seule et l’unique. Cependant, elle brille particulièrement à mes yeux comme stratégie de migration. En effet, quand on part d’une grosse application qui devient de plus en plus complexe à maintenir en terme de props à transmettre, on en revient à la situation pré-Redux. Pour une transition progressive, nous avons d’abord listé tous les composants ayant des props uniquement transmises à leurs enfants. En comptant le nombre de composant par propriété, nous avons pu prioriser les state et props à extraire vers notre store Redux. Cette façon de faire est très efficace pour maximiser l’impact des premières étapes de migration. Idéal dans un premier temps quand on sent qu’on ne va pas avoir le temps de tout migrer que se prévenir de futures difficultés est primordial.

Envie de faire du React avec nous, on recrute !

https://jobs.captaincontrat.com/

--

--