useAction
Registers an action handler — the function the runtime invokes when a trigger handler calls actions.<name>(payload). Handlers can be sync or async; their return value is awaited inside the trigger handler’s run.
Import
Section titled “Import”import { useAction } from '@triggery/react';
Signature
Section titled “Signature”function useAction<S extends TriggerSchema, K extends ActionKey<S>>(
trigger: Trigger<S>,
name: K,
handler: ActionMap<S>[K] extends void
? () => void | Promise<void>
: (payload: ActionMap<S>[K]) => void | Promise<void>,
): void;The handler’s payload parameter is typed from the action schema. Void-payload actions register a () => void | Promise<void> handler.
Parameters
Section titled “Parameters”| Param | Type | Description |
|---|---|---|
trigger | Trigger<S> | The trigger returned by createTrigger. |
name | K extends ActionKey<S> | An action declared in the trigger’s schema. |
handler | Function | Sync or async handler. May return void or Promise<void>. |
Returns
Section titled “Returns”void. The handler is held in a ref and the registration is set up in useEffect / cleaned up on unmount.
Examples
Section titled “Examples”Sync handler
Section titled “Sync handler”import { createTrigger } from '@triggery/core';
import { useAction } from '@triggery/react';
const trigger = createTrigger<{
events: { 'new-message': { author: string } };
actions: { showToast: { title: string; body: string } };
}>({
id: 'demo',
events: ['new-message'],
handler({ event, actions }) {
actions.showToast?.({ title: event.payload.author, body: 'hi' });
},
});
function NotificationLayer() {
useAction(trigger, 'showToast', ({ title, body }) => {
// ^^^^^ payload is typed from the schema
console.log('toast', title, body);
});
return null;
}Async handler with AbortSignal
Section titled “Async handler with AbortSignal”The runtime drives the trigger handler — and therefore your async action — under the trigger’s concurrency strategy. For take-latest the AbortSignal in your trigger handler’s ctx is the one to pass downstream; if your action also wants its own abort, plumb a controller in.
import { createTrigger } from '@triggery/core';
import { useAction } from '@triggery/react';
const trigger = createTrigger<{
events: { 'submit-form': { url: string; body: unknown } };
actions: { post: { url: string; body: unknown } };
}>({
id: 'demo',
events: ['submit-form'],
async handler({ event, actions, signal }) {
await actions.post?.(event.payload);
signal.throwIfAborted();
},
});
function Network() {
useAction(trigger, 'post', async ({ url, body }) => {
await fetch(url, { method: 'POST', body: JSON.stringify(body) });
});
return null;
}Multiple reactors
Section titled “Multiple reactors”If you mount two components both calling useAction(trigger, 'showToast', …), the most recently mounted wins, and a DEV warn-once is logged. On unmount the previous handler is restored. See Ownership.