Controller & events
Use the controller to drive a table from application UI. Use events to observe accepted changes.
Get the controller by ref
Section titled “Get the controller by ref”import { type TableController } from '@inertiax/core';import { InertiaX } from '@inertiax/react-inertia';import { useRef } from 'react';
export function UsersTable() { const controllerRef = useRef<TableController>(null);
return ( <> <button onClick={() => controllerRef.current?.refresh()}> Refresh users </button> <InertiaX prop="users" controllerRef={controllerRef} /> </> );}The ref is set while the renderer owns the session and cleared on unmount.
Declare @inertiax/core as a direct dependency when importing its controller or event types.
Controller operations
Section titled “Controller operations”| Operation | Argument or result |
|---|---|
getState() |
Immutable TableState snapshot |
setPage(page) |
Positive page number supported by the current result |
setPageSize(pageSize) |
One enabled page-size option; resets page to 1 |
setSorting(sorting) |
Ordered array of { key, direction: 'asc' | 'desc' }; resets page to 1 |
setFilters(filters) |
{ operator: 'and' | 'or', conditions: [...] }; each condition is { key, clause, value } or a nested group; resets page to 1 |
setSearch(search) |
String, trimmed by the session; resets page to 1 |
getSelection() |
Immutable array of current-result string or JavaScript-safe integer row IDs |
setSelection(selection) |
Current-result string or JavaScript-safe integer row IDs; use clearSelection() for an empty selection |
getColumnVisibility() |
Immutable { [columnKey]: boolean } map |
setColumnVisibility(visibility) |
Partial visibility map merged into current state; keys must be declared, toggleable columns |
resetColumnVisibility() |
Restore visibility from the current Column definitions |
refresh() |
Immediately request the current server state |
retry() |
Immediately replay the state from the current failed request |
For example:
controller.setSorting([ { key: 'role', direction: 'asc' }, { key: 'name', direction: 'desc' },]);
controller.setFilters({ operator: 'and', conditions: [{ key: 'status', clause: 'equals', value: 'active' }],});
controller.setSelection(['user_42']);controller.setColumnVisibility({ email: false });These operations validate state and use the configured integration. Do not mutate the returned state object or construct Inertia URLs yourself. Search and filter requests use the configured debounce; page, page-size, sorting, refresh, and retry requests are immediate. Selection and column visibility are client-only and do not dispatch a request.
Inside a custom renderer region, use useTableController() instead of threading the ref.
Retry only a failed request
Section titled “Retry only a failed request”retry() is available only while request status is error. It creates a fresh request identity and
uses the failed request’s state, even if other state has since changed locally. Calling it while
idle, scheduled, pending, successful, or externally invalid fails with
INERTIAX_TABLE_SESSION_RETRY_UNAVAILABLE; a disposed session instead rejects every controller
operation as disposed. Use refresh() when you want the current state rather than the failed
request’s state.
Observe events
Section titled “Observe events”Event handlers can be application-scoped or component-scoped:
<InertiaX prop="users" table={{ events: { selectionChange(event) { console.log(event.selection); }, requestError(event) { reportError(event.error); }, copySuccess(event) { analytics.track('table_cell_copied', { column: event.columnKey, row: event.rowId, }); }, }, }}/>The eight supported event keys and their distinguishing payloads are:
| Event | Emitted when and payload |
|---|---|
stateChange |
Any accepted transition, browser-location update, or result reconciliation changes state; includes componentId, source, previousState, and state |
requestStart |
An integration request begins; includes request with its identity, reason, state, request key, and cancellation signal |
requestSuccess |
The accepted latest request succeeds; includes request and result |
requestError |
The accepted latest request fails; includes request and error |
selectionChange |
A controller or built-in UI selection transition is accepted; includes componentId, selection, and state |
columnVisibilityChange |
A controller or built-in UI visibility transition is accepted; includes componentId, columnVisibility, and state |
copySuccess |
A cell value is copied; includes componentId, columnKey, and rowId |
copyError |
Copying fails; includes the copy fields plus error |
A result can prune selection or reset visibility while reconciling new definitions. Observe that
through stateChange with source: 'result'; it is not a second controller transition and does not
also emit selectionChange or columnVisibilityChange. Cancelled or stale requests likewise do not
emit success or error events.
Provider and component handlers both observe their scope. When both exist, the provider handler runs first and the component handler runs second. Events are immutable snapshots. Treat them as notifications; dispatch new state through the controller rather than modifying an event. A handler exception is rethrown asynchronously and does not become a Table request failure.
Read reactive state
Section titled “Read reactive state”Custom content inside the renderer can subscribe through hooks:
import { useTableController, useTableState } from '@inertiax/react';
function SelectionSummary() { const state = useTableState(); const controller = useTableController();
return ( <button disabled={state.selection.length === 0} onClick={() => controller.clearSelection()} > Clear {state.selection.length} selected rows </button> );}useTableSnapshot() returns state, the current result envelope, and status from one immutable
snapshot. useTableState(), useTableStatus(), and useTableEnvelope() subscribe to the narrower
slice. These hooks must run inside the current Table renderer scope.
For operations using selected IDs, see Authorization & security.