React Hooks
useSubscribe
Section titled “useSubscribe”Subscribe to events within React components.
Signature
Section titled “Signature”function useSubscribe<TEventName extends EventNames<TEvents>>( eventName: TEventName, handler: (payload: EventPayload<TEvents, TEventName>) => void, deps: React.DependencyList, options?: { enabled?: boolean }): void;import { useSubscribe } from "./pubsub";
function MyComponent() { const [messages, setMessages] = useState([]);
useSubscribe( "message.received", (payload) => { setMessages((prev) => [...prev, payload]); }, [] );
return <div>{/* ... */}</div>;}With Dependencies
Section titled “With Dependencies”Re-subscribe when dependencies change:
function UserMessages({ userId }) { useSubscribe( "message.received", (payload) => { if (payload.userId === userId) { // Handle message for this user } }, [userId] );}Conditional Subscription
Section titled “Conditional Subscription”function ConditionalSubscriber({ enabled }) { useSubscribe( "notification", (payload) => { console.log("Received:", payload); }, [enabled], { enabled } // Only subscribe when enabled is true );}usePublish
Section titled “usePublish”Get a publish function for sending events.
Signature
Section titled “Signature”function usePublish(): { publish: <TEventName extends EventNames<TEvents>>( eventName: TEventName, payload: EventPayload<TEvents, TEventName> ) => Promise<void>;};import { usePublish } from "./pubsub";
function SendButton() { const { publish } = usePublish();
const handleClick = async () => { await publish("button.clicked", { buttonId: "send", timestamp: Date.now(), }); };
return <button onClick={handleClick}>Send</button>;}With Loading State
Section titled “With Loading State”function SendForm() { const { publish } = usePublish(); const [loading, setLoading] = useState(false);
const handleSubmit = async (data) => { setLoading(true); try { await publish("form.submitted", data); } finally { setLoading(false); } };
return ( <form onSubmit={handleSubmit}> <button disabled={loading}> {loading ? "Sending..." : "Submit"} </button> </form> );}Creating Custom Hooks
Section titled “Creating Custom Hooks”Build custom hooks on top of PubSubJS hooks:
useLatestEvent
Section titled “useLatestEvent”function useLatestEvent<T extends EventNames<Events>>(eventName: T) { const [latest, setLatest] = useState<EventPayload<Events, T> | null>(null);
useSubscribe( eventName, (payload) => { setLatest(payload); }, [eventName] );
return latest;}
// Usagefunction PriceDisplay() { const price = useLatestEvent("price.updated"); return <span>{price?.value ?? "Loading..."}</span>;}useEventHistory
Section titled “useEventHistory”function useEventHistory<T extends EventNames<Events>>( eventName: T, maxItems = 10) { const [history, setHistory] = useState<EventPayload<Events, T>[]>([]);
useSubscribe( eventName, (payload) => { setHistory((prev) => [...prev.slice(-(maxItems - 1)), payload]); }, [eventName, maxItems] );
return history;}
// Usagefunction ActivityFeed() { const activities = useEventHistory("activity.logged", 50); return ( <ul> {activities.map((a, i) => ( <li key={i}>{a.description}</li> ))} </ul> );}useEventCallback
Section titled “useEventCallback”function useEventCallback<T extends EventNames<Events>>(eventName: T) { const { publish } = usePublish();
return useCallback( (payload: EventPayload<Events, T>) => { return publish(eventName, payload); }, [publish, eventName] );}
// Usagefunction ChatInput() { const sendMessage = useEventCallback("chat.message");
const handleSubmit = (text) => { sendMessage({ text, timestamp: Date.now() }); };
return <input onSubmit={handleSubmit} />;}