Slice hooks
Four hooks each return one slice of the state managed by <GristWidgetProvider>. They re-render only when their slice changes. Use them when:
- Profiling shows excessive re-renders from
useGrist(). - A leaf component only cares about one concern (status, theme, writes).
All slice hooks must be called inside <GristWidgetProvider>.
useGristStatus
ts
import { useGristStatus } from "grist-widget-sdk"
function StatusBar() {
const { status, isReady, error, reload, currentTableId } = useGristStatus()
}Returns:
ts
type UseGristStatusResult = {
status: GristWidgetStatus // "booting" | "unavailable" | "ready" | "error"
isAvailable: boolean | null // null while the SDK is still probing
isReady: boolean // `status === "ready"`
error: string | null // last connection error
reload: () => Promise<void> // re-run the handshake
docApi: GristDocApi | null // raw plugin-api handle for advanced use
currentTableId: string | null // selected section's table id
currentTableLoading: boolean
refreshCurrentTable: () => Promise<void>
tableError: string | null // last error reading the table id
}Re-renders when status, table id, or table loading state changes.
useGristSelection
ts
import { useGristSelection } from "grist-widget-sdk"
function RowPanel<TRow, TMapped>() {
const {
record,
records,
mappedRecord,
mappings,
recordsMappings,
newRecordMappings,
columnMappingStatus,
mode,
isNewRecord,
widgetOptions,
widgetInteraction,
mapBack,
mapBackSkipped,
resolveMappedColumnId,
} = useGristSelection<TRow, TMapped>()
}Re-renders when any of the selection / mapping / widget-options fields change. Use this in big trees that read the row but never trigger writes.
useGristWrites
ts
import { useGristWrites } from "grist-widget-sdk"
function ActionButton() {
const { table, getTable, applyActions, actionStatus, actionError } = useGristWrites()
}Re-renders only when actionStatus / actionError change. The function identities (table, getTable, applyActions) are stable.
useGristTheme
ts
import { useGristTheme } from "grist-widget-sdk"
function ThemeRoot() {
const { theme } = useGristTheme()
return <div data-theme={theme ?? "light"}>…</div>
}Returns:
ts
type UseGristThemeResult = {
theme: "light" | "dark" | null
}Re-renders only on theme change.
Choosing between useGrist() and the slice hooks
Use this rule of thumb:
| Component | Prefer |
|---|---|
| Root layout, leaf with most fields used | useGrist() |
| Status bar, error bar, retry button | useGristStatus() |
| Display tree (cards, lists, tables) | useGristSelection() |
| Action panel, toolbar, form save button | useGristWrites() |
| Theme-aware wrapper | useGristTheme() |
You can mix freely — the same provider serves all of them.