Maison >interface Web >js tutoriel >Architecture pilotée par les événements pour la communication des composants Clean React
Vous en avez assez de l'enchevêtrement sans fin de chaînes de forage et de rappel d'accessoires dans vos applications React ? La gestion de l'état et de la communication entre des composants profondément imbriqués ressemble-t-elle à lutter avec du code spaghetti ?
Une architecture basée sur les événements peut simplifier les interactions de vos composants, réduire la complexité et rendre votre application plus maintenable. Dans cet article, je vais vous montrer comment utiliser un hook useEvent personnalisé pour découpler les composants et améliorer la communication au sein de votre application React.
Laissez-moi vous expliquer, commençons par
Dans le développement d'applications modernes, la gestion de l'état et de la communication entre les composants peut rapidement devenir fastidieuse. Cela est particulièrement vrai dans les scénarios impliquant du perçage d'accessoires (dans lequel les données doivent être transmises à travers plusieurs niveaux de composants imbriqués) et des chaînes de rappel, qui peuvent conduire à une logique embrouillée et rendre le code plus difficile à utiliser. maintenir ou déboguer.
Ces défis créent souvent des composants étroitement couplés, réduisent la flexibilité et augmentent la charge cognitive des développeurs qui tentent de retracer la façon dont les données circulent dans l'application. Sans une meilleure approche, cette complexité peut ralentir considérablement le développement et conduire à une base de code fragile.
Dans une application React typique, les composants parents transmettent des accessoires à leurs enfants, et les enfants communiquent en retour avec le parent en déclenchant des rappels. Cela fonctionne bien pour les arbres de composants peu profonds, mais à mesure que la hiérarchie s'approfondit, les choses commencent à devenir compliquées :
Props Drilling : les données doivent être transmises manuellement à travers plusieurs niveaux de composants, même si seul le composant le plus profond en a besoin.
Chaînes de rappel : de même, les composants enfants doivent transmettre les gestionnaires d'événements vers le haut de l'arborescence, créant ainsi des structures étroitement couplées et difficiles à maintenir.
Prenons ce scénario, par exemple :
Cette configuration devient plus difficile à gérer à mesure que l'application se développe. Les composants intermédiaires n'agissent souvent que comme des intermédiaires, transmettant des accessoires et des rappels, ce qui gonfle le code et réduit la maintenabilité.
Pour résoudre le problème du forage d'accessoires, nous nous tournons souvent vers des solutions telles que les bibliothèques globales de gestion d'état (par exemple, Zustand) pour rationaliser le partage de données. Mais qu’en est-il de la gestion des rappels ?
C’est là qu’une approche événementielle peut changer la donne. En découplant les composants et en nous appuyant sur des événements pour gérer les interactions, nous pouvons considérablement simplifier la gestion des rappels. Explorons comment cette approche fonctionne.
Au lieu de s'appuyer sur des rappels directs pour communiquer dans l'arborescence, une architecture basée sur les événements découple les composants et centralise la communication. Voici comment cela fonctionne :
Lorsque SubChildren N déclenche un événement (par exemple, onMyEvent), il n'appelle pas directement de rappel dans le parent.
Au lieu de cela, il distribue un événement qui est géré par un gestionnaire d'événements centralisé.
Le Gestionnaire d'événements écoute l'événement distribué et le traite.
Il peut avertir le Parent (ou tout autre élément intéressé) ou déclencher des actions supplémentaires selon les besoins.
Les accessoires sont toujours transmis dans la hiérarchie, garantissant que les composants reçoivent les données dont ils ont besoin pour fonctionner.
Ceci peut être résolu avec des outils de gestion d'état centralisés comme zustand, redux, mais ne sera pas abordé dans cet article.
Mais, comment mettre en œuvre cette architecture ?
Créons un hook personnalisé appelé useEvent, ce hook sera chargé de gérer l'abonnement aux événements et de renvoyer une fonction de répartition pour déclencher l'événement cible.
Comme j'utilise TypeScript, je dois étendre l'interface de la fenêtre Event afin de créer des événements personnalisés :
interface AppEvent<PayloadType = unknown> extends Event { detail: PayloadType; } export const useEvent = <PayloadType = unknown>( eventName: keyof CustomWindowEventMap, callback?: Dispatch<PayloadType> | VoidFunction ) => { ... };
Ce faisant, nous pouvons définir une carte d'événements personnalisée et transmettre des paramètres personnalisés :
interface AppEvent<PayloadType = unknown> extends Event { detail: PayloadType; } export interface CustomWindowEventMap extends WindowEventMap { /* Custom Event */ onMyEvent: AppEvent<string>; // an event with a string payload } export const useEvent = <PayloadType = unknown>( eventName: keyof CustomWindowEventMap, callback?: Dispatch<PayloadType> | VoidFunction ) => { ... };
Maintenant que nous avons défini les interfaces nécessaires, voyons le code de hook final
import { useCallback, useEffect, type Dispatch } from "react"; interface AppEvent<PayloadType = unknown> extends Event { detail: PayloadType; } export interface CustomWindowEventMap extends WindowEventMap { /* Custom Event */ onMyEvent: AppEvent<string>; } export const useEvent = <PayloadType = unknown>( eventName: keyof CustomWindowEventMap, callback?: Dispatch<PayloadType> | VoidFunction ) => { useEffect(() => { if (!callback) { return; } const listener = ((event: AppEvent<PayloadType>) => { callback(event.detail); // Use `event.detail` for custom payloads }) as EventListener; window.addEventListener(eventName, listener); return () => { window.removeEventListener(eventName, listener); }; }, [callback, eventName]); const dispatch = useCallback( (detail: PayloadType) => { const event = new CustomEvent(eventName, { detail }); window.dispatchEvent(event); }, [eventName] ); // Return a function to dispatch the event return { dispatch }; };
Le hook useEvent est un hook React personnalisé permettant de s'abonner et de distribuer des événements de fenêtre personnalisés. Il vous permet d'écouter des événements personnalisés et de les déclencher avec une charge utile spécifique.
Ce que nous faisons ici est assez simple, nous utilisons le système de gestion d'événements standard et l'étendons afin d'accueillir nos événements personnalisés.
interface AppEvent<PayloadType = unknown> extends Event { detail: PayloadType; } export const useEvent = <PayloadType = unknown>( eventName: keyof CustomWindowEventMap, callback?: Dispatch<PayloadType> | VoidFunction ) => { ... };
Ok cool mais, qu'en est-il d'un
Découvrez ce StackBlitz (s'il ne se charge pas, veuillez le vérifier ici)
Cet exemple simple montre le but du hook useEvent, essentiellement, le bouton du corps distribue un événement qui est intercepté à partir des composants Sidebar, Header et Footer, qui est mis à jour en conséquence.
Cela nous permet de définir des réactions de cause à effet sans avoir besoin de propager un rappel à de nombreux composants.
Voici quelques cas d'utilisation réels où le hook useEvent peut simplifier la communication et découpler les composants dans une application React :
Un système de notification nécessite souvent une communication globale.
Scénario :
Solution : utilisez le hook useEvent pour envoyer un événement onNotification avec les détails de la notification. Des composants tels que NotificationBanner et Header peuvent écouter cet événement et se mettre à jour indépendamment.
Lorsqu'un utilisateur change de thème (par exemple, mode clair/sombre), plusieurs composants peuvent devoir répondre.
Scénario :
Avantages : Pas besoin de transmettre l'état du thème ou les fonctions de rappel via des accessoires dans toute l'arborescence des composants.
Implémentez des raccourcis globaux, comme appuyer sur « Ctrl S » pour enregistrer un brouillon ou sur « Échap » pour fermer un modal.
Les applications telles que les applications de chat ou les tableaux de bord en direct nécessitent plusieurs composants pour réagir aux mises à jour en temps réel.
Pour les formulaires complexes comportant plusieurs sections, les événements de validation peuvent être centralisés.
Suivez les interactions des utilisateurs (par exemple, clics sur des boutons, événements de navigation) et envoyez-les à un service d'analyse.
Pour les outils collaboratifs comme les tableaux blancs partagés ou les éditeurs de documents, les événements peuvent gérer les interactions multi-utilisateurs.
En tirant parti du hook useEvent dans ces scénarios, vous pouvez créer des applications modulaires, maintenables et évolutives sans compter sur des accessoires ou des chaînes de rappel profondément imbriqués.
Les événements peuvent transformer la façon dont vous créez des applications React en réduisant la complexité et en améliorant la modularité. Commencez petit : identifiez quelques composants de votre application qui bénéficieraient d'une communication découplée et implémentez le hook useEvent.
Avec cette approche, vous simplifierez non seulement votre code, mais vous faciliterez également sa maintenance et sa mise à l'échelle à l'avenir.
Pourquoi utiliser les événements ?
Les événements brillent lorsque vous avez besoin que vos composants réagissent à quelque chose qui s'est produit ailleurs dans votre application, sans introduire de dépendances inutiles ni de chaînes de rappel alambiquées. Cette approche réduit la charge cognitive et évite les pièges liés au couplage étroit de composants.
Ma recommandation
Utilisez des événements pour la communication entre composants : lorsqu'un composant doit informer les autres d'une action ou d'un changement d'état, quel que soit leur emplacement dans l'arborescence des composants.
Évitez d'utiliser des événements pour la communication intra-composant, en particulier pour les composants étroitement liés ou directement connectés. Pour ces scénarios, comptez sur les mécanismes intégrés de React tels que les accessoires, l'état ou le contexte.
Une approche équilibrée
Même si les événements sont puissants, leur utilisation excessive peut conduire au chaos. Utilisez-les judicieusement pour simplifier la communication entre des composants faiblement connectés, mais ne les laissez pas remplacer les outils standard de React pour gérer les interactions locales.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!