React hooks
@conexus-x/sdk/react — a separate entry point from the framework-free core, so a view written in Svelte, Vue or plain JS never pays for React it does not use. A view is fundamentally a subscription problem: the module moves under it as the person switches collection, a colleague edits a cell, the theme flips. Hooks are the right shape for that; hand-rolled listen/unsubscribe in useEffect is where the leaks live.
Connection
| Hook | Returns |
|---|---|
useConnection() | { status: "connecting" | "ready" | "error", connection, error } |
useViewContext() | The live ViewContext, re-rendering as the person moves around the module. |
useSettings<T>() | This view instance's configured settings, typed to your own shape. |
useSelection() | string[] — the rows currently selected on the module. |
useScope(scope) | boolean — was this scope actually granted? Renders false until connected, never throws. |
Data
Each of these wraps the general-purpose useConexusQuery, refetching automatically on the realtime event that could plausibly have changed its data — never on an unrelated one.
| Hook | Refetches on |
|---|---|
useRecords(collectionId) | record or recordValue changes |
useModules(workspaceId) | module changes — the hook a workspace-level view needs, since it has no collection to list records from |
useCollections(moduleId) | collection changes |
useColumns(moduleId) | column changes |
Each returns { data, loading, error, refresh }. Build your own with useConexusQuery(fetcher, options) when none of the above fit — same shape, your own fetcher and refetch condition.
const { data: records, loading, error, refresh } = useRecords(context?.collectionId);
// A custom one, refetching only on an amendment:
const { data } = useConexusQuery(
(cx) => cx.api.amendments.list(recordId),
{ deps: [recordId], shouldRefetch: (e) => e.entity === "amendment" }
);Subscribing directly
useConexusEvent(topic, handler) — for anything the data hooks above do not cover. The handler is held in a ref internally, so passing an inline arrow never resubscribes on every render.
Chrome
| Hook | What it does |
|---|---|
useAutoResize(ref?) | Keeps the iframe as tall as the content. Opt-in, like the underlying call. |
useCommands() | { notice, openRecord, confirm, navigate, copyToClipboard } — bound and stable across renders. |
One client per page
Every hook shares a single client memoised at module scope — a view iframe has exactly one parent host, so a context provider would be ceremony around a value that can never legitimately differ between two subtrees. Pass an explicit client argument to any hook only if you genuinely need a second one.