Hooks Overview
The three core hooks
Section titled “The three core hooks”| Hook | When to use it | Returns |
|---|---|---|
useQuery | List or find nodes. Read-only. | { data, loading, error, reload } |
useMutate | Create, update, delete nodes. | { create, update, remove, restore, mutate } |
useNode | Edit a single node with collaborative rich text. | { data, doc, update, syncStatus, remoteUsers, ... } |
When to use which
Section titled “When to use which”- Listing data (tables, lists, grids, search results) —
useQuery - Reading a single node by ID (detail views, cards) —
useQuery(schema, id) - Creating or deleting —
useMutate - Updating properties on a detail page —
useMutate().updateoruseNode().update - Rich text editing (TipTap, collaborative docs) —
useNode(gives you aY.Doc) - Showing who’s online (presence, cursors) —
useNode(gives youremoteUsersandawareness)
The decision tree
Section titled “The decision tree”Do you need a Yjs document (rich text, canvas)? ├── Yes → useNode └── No ├── Reading data? → useQuery └── Writing data? → useMutateuseNode is the only hook that manages a Yjs document and P2P sync connection. If you don’t need collaborative editing, useQuery + useMutate are simpler and more efficient.
Supporting hooks
Section titled “Supporting hooks”| Hook | Purpose |
|---|---|
useIdentity | Get the current user’s DID and auth status |
useComments | Thread-based comments on any node |
useHistory | Change history for a node |
useUndo | Undo/redo for node changes |
All hooks require XNetProvider
Section titled “All hooks require XNetProvider”Every hook reads from a React context provided by XNetProvider. If you call a hook outside the provider, it throws:
import { XNetProvider } from '@xnet/react'
function App() { return ( <XNetProvider config={{ authorDID, signingKey }}> {/* All hooks work inside here */} <TaskList /> </XNetProvider> )}Data flow
Section titled “Data flow”React Component │ ├── useQuery(TaskSchema, filter) │ └── NodeStore.list() → IndexedDB │ └── subscribes to NodeChangeEvents │ ├── useMutate() │ └── NodeStore.create/update/delete() │ ├── validates against schema │ ├── signs change (Ed25519) │ ├── persists to IndexedDB │ ├── emits NodeChangeEvent → useQuery re-renders │ └── syncs to peers (via SyncManager) │ └── useNode(PageSchema, id) ├── NodeStore (structured properties) └── Y.Doc (rich text) ├── WebRTC sync (via SyncManager or WebSocketSyncProvider) ├── debounced persistence to IndexedDB └── awareness (remote users, cursors)