Heim >Web-Frontend >js-Tutorial >Ereignisgesteuerte Architektur für die Kommunikation von Clean React-Komponenten
Haben Sie genug von dem endlosen Wirrwarr von Requisitenbohrungen und Rückrufketten in Ihren React-Anwendungen? Fühlt sich die Verwaltung des Zustands und der Kommunikation zwischen tief verschachtelten Komponenten wie ein Ringen mit Spaghetti-Code an?
Eine ereignisgesteuerte Architektur kann Ihre Komponenteninteraktionen vereinfachen, die Komplexität reduzieren und Ihre App wartbarer machen. In diesem Artikel zeige ich Ihnen, wie Sie einen benutzerdefinierten useEvent-Hook verwenden, um Komponenten zu entkoppeln und die Kommunikation in Ihrer React-App zu verbessern.
Lassen Sie mich Sie durch die Sache führen. Beginnen wir mit
In der modernen Anwendungsentwicklung kann die Verwaltung des Status und der Kommunikation zwischen Komponenten schnell mühsam werden. Dies gilt insbesondere in Szenarien mit Requisiten-Drilling – bei denen Daten über mehrere Ebenen verschachtelter Komponenten weitergegeben werden müssen – und Rückrufketten, was zu einer verworrenen Logik führen und die Codeausführung erschweren kann pflegen oder debuggen.
Diese Herausforderungen führen häufig zu eng gekoppelten Komponenten, verringern die Flexibilität und erhöhen die kognitive Belastung für Entwickler, die versuchen, den Datenfluss durch die Anwendung zu verfolgen. Ohne einen besseren Ansatz kann diese Komplexität die Entwicklung erheblich verlangsamen und zu einer brüchigen Codebasis führen.
In einer typischen React-Anwendung übergeben übergeordnete Komponenten Requisiten an ihre untergeordneten Komponenten, und untergeordnete Komponenten kommunizieren mit dem übergeordneten Element, indem sie Rückrufe auslösen. Dies funktioniert gut für flache Komponentenbäume, aber je tiefer die Hierarchie wird, desto chaotischer wird es:
Props Drilling: Daten müssen manuell über mehrere Komponentenebenen weitergegeben werden, auch wenn dies nur für die tiefste Komponente erforderlich ist.
Rückrufketten: Ebenso müssen untergeordnete Komponenten Ereignishandler im Baum nach oben weiterleiten, wodurch eng gekoppelte und schwer zu wartende Strukturen entstehen.
Nehmen Sie zum Beispiel dieses Szenario:
Diese Einrichtung wird schwieriger zu verwalten, wenn die Anwendung wächst. Zwischenkomponenten fungieren oft nur als Mittelsmänner, die Requisiten und Rückrufe weiterleiten, was den Code aufbläht und die Wartbarkeit verringert.
Um Props Drilling anzugehen, greifen wir häufig auf Lösungen wie globale Zustandsverwaltungsbibliotheken (z. B. Zustand) zurück, um den Datenaustausch zu optimieren. Aber wie sieht es mit der Verwaltung von Rückrufen aus?
Hier kann ein ereignisgesteuerter Ansatz bahnbrechend sein. Durch die Entkopplung von Komponenten und die Verwendung von Ereignissen zur Abwicklung von Interaktionen können wir die Rückrufverwaltung erheblich vereinfachen. Lassen Sie uns untersuchen, wie dieser Ansatz funktioniert.
Anstatt sich bei der Kommunikation im Baum auf direkte Rückrufe zu verlassen, entkoppelt eine ereignisgesteuerte Architektur Komponenten und zentralisiert die Kommunikation. So funktioniert es:
Wenn SubChildren N ein Ereignis auslöst (z. B. onMyEvent), ruft es nicht direkt einen Rückruf im übergeordneten Element auf.
Stattdessen wird ein Ereignis ausgelöst, das von einem zentralen Ereignishandler verarbeitet wird.
Der Ereignishandler wartet auf das ausgelöste Ereignis und verarbeitet es.
Es kann das übergeordnete Element (oder eine andere interessierte Komponente) benachrichtigen oder bei Bedarf zusätzliche Aktionen auslösen.
Requisiten werden weiterhin in der Hierarchie weitergegeben, um sicherzustellen, dass Komponenten die Daten erhalten, die sie zum Funktionieren benötigen.
Dies kann mit zentralisierten Zustandsverwaltungstools wie Zustand und Redux gelöst werden, wird aber in diesem Artikel nicht behandelt.
Aber wie implementieren wir diese Architektur?
Lassen Sie uns einen benutzerdefinierten Hook namens useEvent erstellen. Dieser Hook ist für die Abwicklung des Ereignisabonnements und die Rückgabe einer Versandfunktion zum Auslösen des Zielereignisses verantwortlich.
Da ich Typoskript verwende, muss ich die Ereignisschnittstelle des Fensters erweitern, um benutzerdefinierte Ereignisse zu erstellen:
interface AppEvent<PayloadType = unknown> extends Event { detail: PayloadType; } export const useEvent = <PayloadType = unknown>( eventName: keyof CustomWindowEventMap, callback?: Dispatch<PayloadType> | VoidFunction ) => { ... };
Auf diese Weise können wir eine benutzerdefinierte Ereigniszuordnung definieren und benutzerdefinierte Parameter übergeben:
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 ) => { ... };
Da wir nun die benötigten Schnittstellen definiert haben, sehen wir uns den endgültigen Hook-Code an
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 }; };
Der useEvent-Hook ist ein benutzerdefinierter React-Hook zum Abonnieren und Versenden benutzerdefinierter Fensterereignisse. Es ermöglicht Ihnen, auf benutzerdefinierte Ereignisse zu warten und diese mit einer bestimmten Nutzlast auszulösen.
Was wir hier tun, ist ziemlich einfach: Wir verwenden das Standard-Event-Management-System und erweitern es, um unsere individuellen Events zu ermöglichen.
interface AppEvent<PayloadType = unknown> extends Event { detail: PayloadType; } export const useEvent = <PayloadType = unknown>( eventName: keyof CustomWindowEventMap, callback?: Dispatch<PayloadType> | VoidFunction ) => { ... };
Okay, cool, aber wie wäre es mit einem
Schauen Sie sich diesen StackBlitz an (Wenn er nicht geladen wird, überprüfen Sie ihn bitte hier)
Dieses einfache Beispiel zeigt den Zweck des useEvent-Hooks. Im Grunde löst die Schaltfläche des Körpers ein Ereignis aus, das von Seitenleisten-, Kopf- und Fußzeilenkomponenten abgefangen und entsprechend aktualisiert wird.
Dadurch können wir Ursache-Wirkungs-Reaktionen definieren, ohne dass ein Callback an viele Komponenten weitergegeben werden muss.
Hier sind einige reale Anwendungsfälle, bei denen der useEvent-Hook die Kommunikation vereinfachen und Komponenten in einer React-Anwendung entkoppeln kann:
Ein Benachrichtigungssystem erfordert oft globale Kommunikation.
Szenario:
Lösung: Verwenden Sie den useEvent-Hook, um ein onNotification-Ereignis mit den Benachrichtigungsdetails auszulösen. Komponenten wie das NotificationBanner und der Header können dieses Ereignis abhören und unabhängig voneinander aktualisieren.
Wenn ein Benutzer das Thema umschaltet (z. B. Hell-/Dunkelmodus), müssen möglicherweise mehrere Komponenten reagieren.
Szenario:
Vorteile: Der Themenstatus oder die Rückruffunktionen müssen nicht über Requisiten im gesamten Komponentenbaum übergeben werden.
Implementieren Sie globale Verknüpfungen, z. B. das Drücken von „Strg S“, um einen Entwurf zu speichern, oder „Escape“, um ein Modal zu schließen.
Anwendungen wie Chat-Apps oder Live-Dashboards erfordern mehrere Komponenten, um auf Echtzeitaktualisierungen zu reagieren.
Bei komplexen Formularen mit mehreren Abschnitten können Validierungsereignisse zentralisiert werden.
Verfolgen Sie Benutzerinteraktionen (z. B. Schaltflächenklicks, Navigationsereignisse) und senden Sie sie an einen Analysedienst.
Für kollaborative Tools wie gemeinsame Whiteboards oder Dokumenteditoren können Ereignisse Mehrbenutzerinteraktionen verwalten.
Durch die Nutzung des useEvent-Hooks in diesen Szenarien können Sie modulare, wartbare und skalierbare Anwendungen erstellen, ohne auf tief verschachtelte Requisiten oder Rückrufketten angewiesen zu sein.
Ereignisse können die Art und Weise, wie Sie React-Anwendungen erstellen, verändern, indem sie die Komplexität reduzieren und die Modularität verbessern. Fangen Sie klein an – identifizieren Sie einige Komponenten in Ihrer App, die von einer entkoppelten Kommunikation profitieren würden, und implementieren Sie den useEvent-Hook.
Mit diesem Ansatz vereinfachen Sie nicht nur Ihren Code, sondern machen ihn in Zukunft auch einfacher zu warten und zu skalieren.
Warum Ereignisse verwenden?
Ereignisse kommen zum Tragen, wenn Ihre Komponenten auf etwas reagieren müssen, das an anderer Stelle in Ihrer Anwendung passiert ist, ohne unnötige Abhängigkeiten oder komplizierte Rückrufketten einzuführen. Dieser Ansatz reduziert die kognitive Belastung und vermeidet die Fallstricke einer engen Kopplung von Komponenten.
Meine Empfehlung
Verwenden Sie Ereignisse für die Kommunikation zwischen Komponenten – wenn eine Komponente andere über eine Aktion oder Zustandsänderung benachrichtigen muss, unabhängig von ihrer Position im Komponentenbaum.
Vermeiden Sie die Verwendung von Ereignissen für die komponenteninterne Kommunikation, insbesondere für Komponenten, die eng miteinander verbunden oder direkt verbunden sind. Verlassen Sie sich für diese Szenarien auf die integrierten Mechanismen von React wie Requisiten, Status oder Kontext.
Ein ausgewogener Ansatz
Obwohl Ereignisse mächtig sind, kann ihre übermäßige Nutzung zu Chaos führen. Setzen Sie sie mit Bedacht ein, um die Kommunikation über lose verbundene Komponenten hinweg zu vereinfachen, aber lassen Sie nicht zu, dass sie die Standardtools von React zur Verwaltung lokaler Interaktionen ersetzen.
Das obige ist der detaillierte Inhalt vonEreignisgesteuerte Architektur für die Kommunikation von Clean React-Komponenten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!