Skip to main content
Version: 0.1.0

EventContext

A factory function that creates a fully typed pub/sub event system backed by React Context. Import it from the dedicated entry point:

import { factory } from "@julianfere/hooked/events";

factory<AppEvents>()

function factory<AppEvents extends Record<string, any>>(): {
createEventContext: () => Context<IEventContext<AppEvents>>;
createEventProvider: (ctx: Context<IEventContext<AppEvents>>) =>
({ children }: PropsWithChildren) => JSX.Element;
createEventHook: (ctx: Context<IEventContext<AppEvents>>) =>
() => IEventContext<AppEvents>;
}

The generic AppEvents defines the event map — keys are event names, values are their payload types.

Setup (one-time)

// events.ts
import { factory } from "@julianfere/hooked/events";

interface AppEvents {
userLoggedIn: { id: string; name: string };
userLoggedOut: never;
cartUpdated: { itemCount: number };
}

const { createEventContext, createEventProvider, createEventHook } =
factory<AppEvents>();

export const EventCtx = createEventContext();
export const EventsProvider = createEventProvider(EventCtx);
export const useEvents = createEventHook(EventCtx);

Wrap your app

// main.tsx
import { EventsProvider } from "./events";

<EventsProvider>
<App />
</EventsProvider>

Use in components

import { useEvents } from "./events";

function LoginButton() {
const { publish } = useEvents();

return (
<button onClick={() => publish("userLoggedIn", { id: "1", name: "Alice" })}>
Log in
</button>
);
}

function Navbar() {
const { subscribe } = useEvents();

useEffect(() => {
const unsub = subscribe("userLoggedIn", ({ name }) => {
console.log(`Welcome, ${name}!`);
});
return unsub; // unsubscribes on unmount
}, [subscribe]);

return <nav></nav>;
}

Hook API

MethodSignatureDescription
publish(eventName, payload) => voidEmit an event to all current subscribers
subscribe(eventName, callback) => () => voidRegister a listener. Returns an unsubscribe function

Error handling

useEvents() throws if called outside of its EventsProvider. Always ensure the provider wraps every component that uses the hook.

Live example

Loading playground...