Skip to content
GitHubXDiscord

useEvent

Stable · since 0.1.0

Returns a stable callback that fires a typed event on a trigger. Identity is preserved across renders, so passing it to useEffect dependency lists is safe.

import { useEvent } from '@triggery/react';
function useEvent<S extends TriggerSchema, K extends EventKey<S>>(
  trigger: Trigger<S>,
  eventName: K,
): EventMap<S>[K] extends void
  ? () => void
  : (payload: EventMap<S>[K]) => void;

The return type is inferred from the trigger’s schema. Void-payload events return a () => void emitter; otherwise the emitter takes the typed payload.

ParamTypeDescription
triggerTrigger<S>The trigger returned by createTrigger.
eventNameK extends EventKey<S>Must be one of the keys listed in trigger’s events schema and events: [...] array.

A stable emitter function:

  • void payload → () => void
  • Typed payload → (payload: …) => void

The function is wrapped in useCallback, so its identity stays the same as long as runtime and eventName don’t change.

import { createTrigger } from '@triggery/core';
import { useEvent } from '@triggery/react';

const chatTrigger = createTrigger<{
  events: { 'new-message': { author: string; text: string } };
}>({
  id: 'chat',
  events: ['new-message'],
  handler() {},
});

function Chat() {
  const fire = useEvent(chatTrigger, 'new-message');
  return (
    <button type="button" onClick={() => fire({ author: 'Alice', text: 'hi' })}>
      simulate
    </button>
  );
}
import { createTrigger } from '@triggery/core';
import { useEvent } from '@triggery/react';

const readyTrigger = createTrigger<{
  events: { 'app:ready': void };
}>({
  id: 'app-ready',
  events: ['app:ready'],
  handler() {},
});

function Bootstrap() {
  const ready = useEvent(readyTrigger, 'app:ready');
  return <button onClick={() => ready()}>signal ready</button>;
}
import { useEvent } from '@triggery/react';
import { useEffect } from 'react';
import { messageTrigger } from './triggers/message.trigger';

function WebSocketAdapter({ socket }: { socket: WebSocket }) {
  const fireMessage = useEvent(messageTrigger, 'new-message');

  useEffect(() => {
    socket.addEventListener('message', e => fireMessage(JSON.parse(e.data)));
    return () => socket.removeEventListener('message', /* ... */ () => {});
  }, [socket, fireMessage]); // ← stable identity means this effect re-binds rarely
}