DEV Community

Suman Ghosh
Suman Ghosh

Posted on

React Messaging Design

Problem Statement:

How do various components communicate with each other?
Problem is to communicate each other component like we have parent component A and child 
components b and c and d so we want when we click on b components c and d component also 
change for this problem we can use different ways using global library like redux, zustand, jotai but this architecture is hard to manage 
 write more code manage many file and slow performance so for solve this problem simply we create a global hub where we manage this so first when we click any component its go to global component and send information what they want 
to send and the global hub react according to it and send data to child component .

Solution:

We can use a custom hook that allows us to decouple event handling and data flow. Instead of relying on props drilling for passing data and events between deeply nested components, we can create an event-driven architecture. In this solution, the custom hook helps listen to events 
and allows components to communicate without having to pass data through intermediate 
components.

Custom Hook (For React Only):

The useEvent hook allows us to subscribe to specific events and dispatch events to notify 
listeners across different components. It enables components to react to events like mapClick 
and perform actions, such as updating state or logging data, without the need for props to be 
passed explicitly.

import { useEffect, useCallback } from "react";
interface AppEvent<PayloadType = unknown> extends Event {
 detail: PayloadType;
}
export const useEvent = <PayloadType = unknown>(
 eventName: string,
 callback?: (payload: PayloadType) => void,
) =>  useEffect(() => {
 if (!callback) return;
 const listener = (event: CustomEvent<PayloadType>) => {
 callback(event.detail);
 };
 window.addEventListener(eventName, listener);
 return () => {
 window.removeEventListener(eventName, listener);
 };
 }, [callback, eventName]);
 const subscribe = useCallback(
 ({ source, input, data }: { source: string; input: string; data: any[] }) => {
 const event = new CustomEvent(source, {
 detail: { input, data },
 });
 window.dispatchEvent(event);
 },
 [],
 );
 return { subscribe };
};         
Enter fullscreen mode Exit fullscreen mode

How It Works:

Listening for Events: The useEvent hook listens for a specific event (e.g., mapClick) and 
executes the provided callback function when that event is triggered
Subscribing to Events: The subscribe function inside the hook allows components to 
trigger events by dispatching them with custom data. In the code example, the subscribe 
function is used to send selected data when a map is clicked.
Decoupling Components: With this setup, components no longer need to pass props 
down the hierarchy. Instead, they can use the useEvent hook to subscribe to and 
dispatch events, making communication between components more efficient and decoupled.

Example Usage:
In the application, we have the following usage:
Subscribing to the mapClick event:

const { subscribe } = useEvent("mapClick");
subscribe({
 source: "mapClick",
 input: "select",
 data: [selectedUnitIds],
});
Handling the event:
useEvent("mapClick", (data: any) => {
 console.log(data);
 });
Enter fullscreen mode Exit fullscreen mode

Benefits:

Decoupled Architecture: Components no longer need to be aware of each other's 
internal state or pass props down multiple layers. They can communicate via events.
Simplified Code: The custom hook abstracts away the complexity of handling events and 
subscribing to them, making the code easier to maintain and extend.
Reusable Logic: The useEvent hook can be reused across different components that 
need to listen for or trigger events, leading to a more modular design.

Top comments (0)