v19.2Latest

Passer à l'échelle avec Reducer et Context

Les reducers vous permettent de consolider la logique de mise à jour de l'état d'un composant. Le Context vous permet de transmettre des informations en profondeur à d'autres composants. Vous pouvez combiner les reducers et le context pour gérer l'état d'un écran complexe.

Vous apprendrez
  • Comment combiner un reducer avec le context
  • Comment éviter de passer l'état et la fonction dispatch via les props
  • Comment conserver la logique du context et de l'état dans un fichier séparé

Combiner un reducer avec le context

Dans cet exemple tiré del'introduction aux reducers, l'état est géré par un reducer. La fonction reducer contient toute la logique de mise à jour de l'état et est déclarée en bas de ce fichier :

Un réducteur aide à garder les gestionnaires d'événements courts et concis. Cependant, à mesure que votre application grandit, vous pourriez rencontrer une autre difficulté.Actuellement, l'étattaskset la fonctiondispatchne sont disponibles que dans le composant de niveau supérieurTaskApp.Pour permettre à d'autres composants de lire la liste des tâches ou de la modifier, vous devez explicitementfaire passerl'état actuel et les gestionnaires d'événements qui le modifient en tant que props.

Par exemple,TaskApppasse une liste de tâches et les gestionnaires d'événements àTaskList:

EtTaskListtransmet les gestionnaires d'événements àTask:

Dans un petit exemple comme celui-ci, cela fonctionne bien, mais si vous avez des dizaines ou des centaines de composants intermédiaires, passer en bas tous les états et les fonctions peut être assez frustrant !

C'est pourquoi, comme alternative à leur passage via les props, vous pourriez vouloir placer à la fois l'étattaskset la fonctiondispatch dans un contexte.De cette façon, tout composant situé en dessous deTaskAppdans l'arbre peut lire les tâches et dispatcher des actions sans le fastidieux « prop drilling ».

Voici comment vous pouvez combiner un réducteur avec un contexte :

  1. Créezle contexte.
  2. Placezl'état et la fonction de dispatch dans le contexte.
  3. Utilisezle contexte n'importe où dans l'arbre.

Étape 1 : Créer le contexte

Le HookuseReducerrenvoie la liste actuelle destaskset la fonctiondispatchqui permet de les mettre à jour :

Pour les transmettre dans l'arbre, vous allezcréerdeux contextes distincts :

  • TasksContextfournit la liste actuelle des tâches.
  • TasksDispatchContextfournit la fonction qui permet aux composants de dispatcher des actions.

Exportez-les depuis un fichier séparé afin de pouvoir les importer ultérieurement depuis d'autres fichiers :

Ici, vous passeznullcomme valeur par défaut aux deux contextes. Les valeurs réelles seront fournies par le composantTaskApp.

Étape 2 : Placer l'état et la fonction de dispatch dans le contexte

Vous pouvez maintenant importer les deux contextes dans votre composantTaskApp. Prenez lestaskset la fonctiondispatchrenvoyées paruseReducer()etfournissez-lesà tout l'arbre situé en dessous :

Pour l'instant, vous transmettez les informations à la fois via les props et dans le contexte :

Dans l'étape suivante, vous allez supprimer le passage des props.

Étape 3 : Utiliser le contexte n'importe où dans l'arbre

Maintenant, vous n'avez plus besoin de passer la liste des tâches ou les gestionnaires d'événements dans l'arbre :

Au lieu de cela, tout composant qui a besoin de la liste des tâches peut la lire depuis leTasksContext:

Pour mettre à jour la liste des tâches, tout composant peut lire la fonctiondispatchdepuis le contexte et l'appeler :

Le composantTaskAppne passe aucun gestionnaire d'événements vers le bas, et le composantTaskListn'en passe pas non plus au composantTask.Chaque composant lit le contexte dont il a besoin :

L'état « réside » toujours dans le composant de niveau supérieurTaskApp, géré avecuseReducer.Mais sestasksetdispatchsont maintenant disponibles pour chaque composant inférieur dans l'arbre en important et utilisant ces contextes.

Regrouper toute la logique dans un seul fichier

Vous n'êtes pas obligé de le faire, mais vous pourriez encore simplifier les composants en déplaçant à la fois le réducteur et le contexte dans un seul fichier. Actuellement,TasksContext.jsne contient que deux déclarations de contexte :

Ce fichier est sur le point de devenir encombré ! Vous allez déplacer le réducteur dans ce même fichier. Ensuite, vous déclarerez un nouveau composantTasksProviderdans le même fichier. Ce composant rassemblera toutes les pièces :

  1. Il gérera l'état avec un réducteur.
  2. Il fournira les deux contextes aux composants enfants.
  3. Il prendra les enfants comme propafin que vous puissiez lui passer du JSX.

Cela supprime toute la complexité et le câblage de votre composantTaskApp :

Vous pouvez également exporter des fonctions quiutilisentle contexte depuisTasksContext.js:

Lorsqu'un composant a besoin de lire le contexte, il peut le faire via ces fonctions :

Cela ne change en rien le comportement, mais cela vous permet de séparer ultérieurement ces contextes ou d'ajouter de la logique à ces fonctions.Maintenant, tout le câblage du contexte et du réducteur se trouve dansTasksContext.js. Cela permet de garder les composants propres et non encombrés, concentrés sur ce qu'ils affichent plutôt que sur l'origine de leurs données :

Vous pouvez considérerTasksProvidercomme une partie de l'écran qui sait comment traiter les tâches,useTaskscomme un moyen de les lire, etuseTasksDispatchcomme un moyen de les mettre à jour depuis n'importe quel composant situé plus bas dans l'arborescence.

Remarque

Les fonctions commeuseTasksetuseTasksDispatchsont appeléesHooks personnalisés.Votre fonction est considérée comme un Hook personnalisé si son nom commence paruse. Cela vous permet d'utiliser d'autres Hooks, commeuseContext, à l'intérieur.

À mesure que votre application grandit, vous pouvez avoir de nombreuses paires contexte-réducteur comme celle-ci. C'est un moyen puissant de faire évoluer votre application et deremonter l'étatsans trop d'effort chaque fois que vous souhaitez accéder aux données profondément dans l'arbre.

Récapitulatif

  • Vous pouvez combiner un réducteur avec un contexte pour permettre à n'importe quel composant de lire et de mettre à jour l'état au-dessus de lui.
  • Pour fournir l'état et la fonction de dispatch aux composants en dessous :
    1. Créez deux contextes (un pour l'état et un pour les fonctions de dispatch).
    2. Fournissez les deux contextes depuis le composant qui utilise le réducteur.
    3. Utilisez l'un ou l'autre contexte depuis les composants qui ont besoin de les lire.
  • Vous pouvez encore simplifier les composants en déplaçant tout le câblage dans un seul fichier.
    • Vous pouvez exporter un composant commeTasksProviderqui fournit le contexte.
    • Vous pouvez également exporter des Hooks personnalisés commeuseTasksetuseTasksDispatchpour le lire.
  • Vous pouvez avoir de nombreuses paires contexte-réducteur comme celle-ci dans votre application.