Hooks: React hooks for data, connection... · Strata Sync
AI agents: fetch the documentation index at llms.txt . Markdown versions are available by appending .md to any page URL, including this page's markdown .
React hooks for data, connection state, and client access in the sync engine.
All hooks require a SyncProvider. They re-render automatically when data changes.
useModel
Reads a single model by ID. Suspends while bootstrapping or loading a lazy model.
Copy import { Suspense } from "react" ;
import { useModel } from "@stratasync/react" ;
function TaskDetail ({ taskId } : { taskId : string }) {
const task
=
useModel
<
Task
>(
"Task"
, taskId);
if ( ! task) {
return < div >Task not found</ div >;
}
return < div >{task.title}</ div >;
}
// Wrap in Suspense boundary
function TaskPage ({ taskId } : { taskId : string }) {
return (
< Suspense fallback = {< div >Loading...</ div >}>
< TaskDetail taskId = {taskId} />
</ Suspense >
);
}
Signature: useModel<T>(modelName: string, id: string | null | undefined): T | null
Parameter Type Description modelNamestringRegistered model name. idstring | null | undefinedModel ID. Returns null immediately if null or undefined.
Return value: T | null: the model instance or null if not found.
Non-Suspense alternative to useModel. Returns explicit loading and error states.
Copy import { useModelState } from "@stratasync/react" ;
function TaskDetail ({ taskId } : { taskId : string }) {
const {
data : task ,
isLoading ,
isFound ,
error ,
refresh ,
} = useModelState < Task >( "Task" , taskId);
if (isLoading) {
return < div >Loading...</ div >;
}
if (error) {
return < div >Error: {error.message}</ div >;
}
if ( ! isFound) {
return < div >Task not found</ div >;
}
return (
< div >
< h1 >{task.title}</ h1 >
< button onClick = {refresh}>Refresh</ button >
</ div >
);
} Signature: useModelState<T>(modelName: string, id: string | null | undefined): UseModelResult<T>
Field Type Description dataT | nullThe model instance. isLoadingbooleanWhether the model is being loaded. isFoundbooleanWhether the model was found (data !== null). errorError | nullAny error that occurred during loading. refresh() => Promise<void>Manually re-fetch the model.
Alias for useModel that makes the Suspense dependency explicit.
Copy import { useModelSuspense } from "@stratasync/react" ;
function TaskDetail ({ taskId } : { taskId : string }) {
const task = useModelSuspense < Task >( "Task" , taskId);
// Same behavior as useModel
} Signature: useModelSuspense<T>(modelName: string, id: string): T | null
Queries models with filtering, sorting, and pagination. Returns loading states explicitly.
Copy import { useQuery } from "@stratasync/react" ;
function TaskList ({ projectId } : { projectId : string }) {
const {
data : tasks ,
isLoading ,
hasMore ,
totalCount ,
refresh ,
} = useQuery < Task >( "Task" , {
where : ( task ) => task.projectId === projectId,
orderBy : ( a , b ) => a.createdAt - b.createdAt,
limit: 20 ,
});
if (isLoading) {
return < div >Loading...</ div >;
}
return (
< div >
< p >
Showing {tasks. length } of {totalCount} tasks
</ p >
< ul >
{tasks. map (( task ) => (
< li key = {task.id}>{task.title}</ li >
))}
</ ul >
{hasMore && < button onClick = {refresh}>Load more</ button >}
</ div >
);
} Signature: useQuery<T>(modelName: string, options?: UseQueryOptions<T>): UseQueryResult<T>
UseQueryOptions (extends QueryOptions):
Option Type Default Description where(item: T) => boolean- Filter predicate. orderBy(a: T, b: T) => number- Sort comparator. limitnumber- Maximum results. offsetnumber- Results to skip. includeArchivedbooleanfalseInclude archived items. skipbooleanfalseSkip the query entirely.
Field Type Description dataT[]Query results. isLoadingbooleanWhether the query is executing. errorError | nullAny error that occurred. totalCountnumber | undefinedTotal matching count before pagination. hasMorebooleanWhether more results are available. refresh() => Promise<void>Re-execute the query.
Convenience wrapper around useQuery without pagination (limit/offset).
Copy import { useQueryAll } from "@stratasync/react" ;
function AllTasks () {
const { data : tasks , isLoading } = useQueryAll < Task >( "Task" , {
where : ( t ) => t.status !== "done" ,
orderBy : ( a , b ) => a.title. localeCompare (b.title),
});
if (isLoading) {
return < div >Loading...</ div >;
}
return < TaskGrid tasks = {tasks} />;
} Signature: useQueryAll<T>(modelName: string, options?: Omit<UseQueryOptions<T>, "limit" | "offset">): UseQueryResult<T>
Returns the count of matching models without fetching them.
Copy import { useQueryCount } from "@stratasync/react" ;
function TaskCounter ({ projectId } : { projectId : string }) {
const { count , isLoading } = useQueryCount < Task >(
"Task" ,
( task ) => task.projectId === projectId && task.status === "todo"
);
if (isLoading) {
return < span >...</ span >;
}
return < span >{count} tasks</ span >;
} Signature: useQueryCount<T>(modelName: string, where?: (item: T) => boolean): { count: number; isLoading: boolean; error: Error | null }
Field Type Description countnumberNumber of matching models. isLoadingbooleanWhether the count is being computed. errorError | nullAny error that occurred.
Returns sync status, last sync ID, pending count, and error state.
Copy import { useConnectionState } from "@stratasync/react" ;
function SyncStatusBadge () {
const { status , lastSyncId , backlog , error } = useConnectionState ();
if (error) {
return < Badge color = "red" >Error: {error.message}</ Badge >;
}
if (status === "bootstrapping" ) {
return < Badge color = "yellow" >Bootstrapping...</ Badge >;
}
if (status === "syncing" ) {
return (
< Badge color = "green" >
Synced (ID: {lastSyncId}) {backlog > 0 && `- ${ backlog } pending` }
</ Badge >
);
}
return < Badge color = "gray" >{status}</ Badge >;
} Signature: useConnectionState(): UseConnectionStateResult
UseConnectionStateResult:
Field Type Description statusSyncClientStateCurrent sync state: "disconnected", "connecting", "bootstrapping", "syncing", or "error". lastSyncIdnumberLast sync ID received from the server. backlognumberNumber of pending (unsynced) transactions in the outbox. errorError | nullLast sync error, or null if no error.
Returns true when the sync client's connection state is "disconnected".
Copy import { useIsOffline } from "@stratasync/react" ;
function OfflineBanner () {
const isOffline = useIsOffline ();
if ( ! isOffline) {
return null ;
}
return < div >You're offline. Changes will sync when you reconnect.</ div >;
} Signature: useIsOffline(): boolean
Returns the count of unsynced transactions.
Copy import { usePendingCount } from "@stratasync/react" ;
function PendingIndicator () {
const { count , hasPending } = usePendingCount ();
if ( ! hasPending) {
return < span >All changes saved</ span >;
}
return < span >{count} changes pending sync</ span >;
} Signature: usePendingCount(): UsePendingCountResult
Field Type Description countnumberNumber of pending transactions. hasPendingbooleantrue when count > 0.
Trigger a manual sync cycle.
Copy import { useSync } from "@stratasync/react" ;
function SyncButton () {
const { sync , isSyncing } = useSync ();
return (
< button onClick = {sync} disabled = {isSyncing}>
{isSyncing ? "Syncing..." : "Sync Now" }
</ button >
);
} Signature: useSync(): { sync: () => Promise<void>; isSyncing: boolean }
Field Type Description sync() => Promise<void>Triggers client.syncNow(). Guards against concurrent calls. isSyncingbooleantrue while a manual sync is in progress.
Returns the full sync context: client instance, connection state, and derived flags.
Copy import { useSyncClient } from "@stratasync/react" ;
function SyncDebugPanel () {
const {
client ,
state ,
connectionState ,
lastSyncId ,
backlog ,
error ,
isReady ,
isSyncing ,
isOffline ,
clientId ,
} = useSyncClient ();
return (
< pre >
{ JSON . stringify (
{
state,
connectionState,
lastSyncId,
backlog,
isReady,
isOffline,
clientId,
},
null ,
2
)}
</ pre >
);
} Signature: useSyncClient(): SyncContextValue
Field Type Description clientSyncClientThe sync client instance. stateSyncClientStateCurrent sync state. connectionStateConnectionStateCurrent connection state. lastSyncIdnumberLast sync ID from server. backlognumberPending transaction count. errorError | nullLast sync error. isReadybooleantrue when state is "syncing".isSyncingbooleantrue when state is "syncing" or "bootstrapping".isOfflinebooleantrue when connection is "disconnected".clientIdstringClient instance identifier.
Throws an error if called outside of a SyncProvider.
Returns the SyncClient instance for calling client methods directly.
Copy import { useSyncClientInstance } from "@stratasync/react" ;
function CreateTaskButton () {
const client = useSyncClientInstance ();
const handleCreate = async () => {
await client. create ( "Task" , {
title: "New task" ,
status: "todo" ,
});
};
return < button onClick = {handleCreate}>Create Task</ button >;
} Signature: useSyncClientInstance(): SyncClient
true when bootstrapping is complete and the client is in "syncing" state. Gate UI rendering until data is available.
Copy import { useSyncReady } from "@stratasync/react" ;
function AppContent () {
const isReady = useSyncReady ();
if ( ! isReady) {
return < FullPageLoader />;
}
return < Dashboard />;
} Signature: useSyncReady(): boolean
true while a multi-page delta backlog is being fetched and applied, which happens
after a long disconnect. The client stays ready and keeps rendering cached data
throughout, and the whole backlog lands in one update — so use this for a quiet
indicator, not to gate rendering.
Copy import { useSyncCatchingUp } from "@stratasync/react" ;
function CatchUpBadge () {
const isCatchingUp = useSyncCatchingUp ();
if ( ! isCatchingUp) {
return null ;
}
return < span >Catching up…</ span >;
} Signature: useSyncCatchingUp(): boolean
Returns the current SyncClientState string value.
Copy import { useSyncState } from "@stratasync/react" ;
function StateIndicator () {
const state = useSyncState ();
const labels : Record < string , string > = {
disconnected: "Disconnected" ,
connecting: "Connecting..." ,
bootstrapping: "Loading data..." ,
syncing: "Ready" ,
error: "Error" ,
};
return < span >{labels[state] ?? state}</ span >;
} Signature: useSyncState(): SyncClientState
Returns one of: "disconnected", "connecting", "bootstrapping", "syncing", "error".