Sometimes components need to talk to each other without being parent-child related. Instead of prop-drilling or overusing global state, you can build a lightweight event bus pattern in React — perfect for modals, toasts, and real-time collaboration features.

Step 1: Create a Simple Event Emitter


We'll make a minimal pub-sub (publish/subscribe) system.

class EventBus {
constructor() {
this.listeners = {};
}

on(event, callback) {
(this.listeners[event] ||= []).push(callback);
}

off(event, callback) {
if (!this.listeners[event]) return;
this.listeners[event] = this.listeners[event].filter(cb => cb !== callback);
}

emit(event, payload) {
(this.listeners[event] || []).forEach(cb => cb(payload));
}
}

export const eventBus = new EventBus();

Step 2: Fire Events from Anywhere


Any component can now broadcast events across the app.

import { eventBus } from "./eventBus";

function Publisher() {
return (

);
}

Step 3: Listen for Events in Any Component


Use useEffect to subscribe and clean up properly.

import { useEffect, useState } from "react";
import { eventBus } from "./eventBus";

function Subscriber() {
const [message, setMessage] = useState("");

useEffect(() => {
const handler = (payload) => setMessage(payload);
eventBus.on("greet", handler);
return () => eventBus.off("greet", handler);
}, []);

return

Received: {message}
;
}

✅ Pros


  • Instant, decoupled communication across the app.
  • No context providers, Redux, or complex wiring needed.
  • Extremely lightweight (a few dozen lines).

⚠️ Cons


  • No built-in type safety (consider extending for TS users).
  • Harder to trace event flows in large apps without discipline.
  • Not ideal for critical app-wide state (use Context or Redux there).

Wrap-Up


The event bus pattern is perfect for lightweight, decoupled messaging between parts of a React app. It's especially useful for things like modals, notifications, game state, or real-time features where clean hierarchy isn't possible or desirable.

For a much more extensive guide on getting the most out of React portals, check out my full 24-page PDF file on Gumroad. It's available for just $10:

Using React Portals Like a Pro.

Enjoyed this technique? Feel free to support me here: Buy Me a Coffee