Hooks
React hooks for file progress, document data fetching, and OCR records mutations.
useFileProgress
Connects to /api/nexa/progress/:fileId via EventSource and streams real-time progress events.
Return value
| Field | Type | Description |
|---|---|---|
progress | number | 0–100 |
stage | string | Current pipeline stage name |
message | string | Human-readable status message |
isComplete | boolean | true when extraction finished |
records | StudentRecord[] | Extracted records (populated when complete) |
error | string | null | Error message if pipeline failed |
The hook automatically closes the EventSource connection when isComplete is true or the component unmounts.
useNexaContext
Access the configured base path and other SDK context values:
This hook is used internally by all components — you rarely need it directly.
OCR records hooks
All hooks below are exported from @nexa-ed/react and are "use client" — import them only in client components. They wire optimistic cache updates into the TanStack Query cache keyed by getFileStudentRecords.
Info
The cache key is always built from orpc.documents.getFileStudentRecords.queryOptions({ input: { fileId, page, limit, hasWarnings } }).queryKey. Pass identical values to the hooks and to your useQuery call — they must target the same cache entry for optimistic updates to work.
Optimistic update pattern
All mutating hooks follow the same three-step pattern internally:
- Cancel in-flight queries for the affected cache key — prevents a stale refetch from overwriting the optimistic state.
- Patch the cache immediately — the UI updates without waiting for the server.
- Roll back on error — the previous data (saved in
onMutate) is restored.
Screenshot
Optimistic update flow — cell edited, row immediately reflects new value before server responds, then confirmed or rolled back
useColumnSort
Client-side column sort state for RecordDataGrid. Cycles through null → "asc" → "desc" → null on each toggleSort(col) call. Numeric columns (where > 80% of values parse as numbers) use numeric comparison; all others use localeCompare. Null/empty values always sort last.
Screenshot
Column header with sort arrow active — numeric column sorted as numbers, nulls last
useUpdateRecordInList
Optimistic mutation for updating a single record inside the paginated list cache. Rolls back on error.
useAddRowsToList
Optimistically appends new rows to the paginated cache, then creates them on the server. Returns a handleAddRows function rather than a raw mutateAsync — it accepts the target page number (not necessarily the current page) so rows land on the correct page in the cache.
useDeleteRecordFromList
Optimistic delete from the paginated cache. Updates the total count in the pagination metadata immediately.
useSerialRenumber
Batch-renumbers a numeric column across all visible records on the current page. Optimistically patches the cache, sends server updates in chunks of 500, rolls back on error.
Unusual signature: requires an external QueryClient and batchMutateAsync so it can share the parent component's mutation instance rather than creating its own.
To continue a multi-page sequence, track lastSerialNumber from onRenumberComplete and pass lastSerialNumber + 1 as startFrom on the next page.
Screenshot
Renumber action bar open — column selected, start number input, row count shown, Apply button
useUpdatePageRecord
Optimistic update for a record inside the getPageRecordsWithRefinement cache — used by PageDetailPanel, not the main paginated list.
useDeletePageRecord
Optimistic delete from the getPageRecordsWithRefinement cache.
useUploadFile
Handles the full upload flow: get a presigned URL → PUT the file → submit for processing.
Return value
| Field | Type | Description |
|---|---|---|
upload | (file: File) => Promise<string> | Returns fileId on success |
isUploading | boolean | true while upload + submit is in progress |
progress | number | Upload byte progress 0–100 |
fileId | string | null | Set after successful submission |
error | string | null | Error message on failure |