Actions
This guide walks you through defining and executing your first action. Make sure you have completed Installation and Connectivity UI before proceeding.
Your First Action
Define an action that saves data to a server:
// actions/save.ts
import { actionOptions } from "@connectivity-js/core";
export const saveAction = actionOptions({
actionKey: "save",
request: (input: { id: string; data: string }) => api.save(input),
dedupeKey: (input) => input.id,
});Use it in a component:
import { useAction } from "@connectivity-js/react";
import { saveAction } from "./actions/save";
function SaveButton({ id, data }: { id: string; data: string }) {
const { execute, pendingCount } = useAction(saveAction, {
onSuccess: (result) => toast.success("Saved"),
onEnqueued: (jobId) => toast.info("Offline — queued"),
onError: (error) => toast.error("Failed"),
});
return (
<button onClick={() => execute({ id, data })}>
Save {pendingCount > 0 && `(${pendingCount} pending)`}
</button>
);
}Inline definition
If an action isn’t reused, skip actionOptions() and pass config inline. Type inference works the same:
const { execute } = useAction({
actionKey: "save",
request: (input: { id: string; data: string }) => api.save(input),
dedupeKey: (input) => input.id, // input type auto-inferred
});Return value
execute() returns a discriminated union:
const result = await execute({ id: "1", data: "hello" });
if (result.enqueued) {
// Queued (offline or same resource running)
console.log(result.jobId); // string
return;
}
// Immediate execution completed
console.log(result.result); // TResult — inferred from request return typeBranching on result.enqueued automatically narrows the remaining fields.
Next steps
- Offline Behavior —
whenOffline, execution flow, FIFO - Deduplication — collapsing duplicate requests with
dedupeKey
Last updated on