Skip to content

Commit a03b5a5

Browse files
KyleAMathewsclaude
andauthored
docs: improve incremental updates example in query-collection docs (TanStack#703)
* docs: improve incremental updates example in query-collection docs Replace confusing manual optimistic update pattern with familiar onInsert/onUpdate handler pattern. Show how to: - Use persistence handlers (onInsert, onUpdate) like regular collections - Return { refetch: false } to avoid unnecessary refetches - Sync server-computed fields using direct writes within handlers This makes the example more approachable and consistent with the rest of the documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * docs: remove unnecessary writeDelete from query-collection example Optimistic state is automatically removed when the mutation handler returns, so there's no need to manually delete optimistic items. The handler just needs to write the server response to the synced data store, and when it completes, the optimistic state is automatically replaced. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent 8b29841 commit a03b5a5

File tree

1 file changed

+49
-21
lines changed

1 file changed

+49
-21
lines changed

docs/collections/query-collection.md

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -224,28 +224,56 @@ ws.on('todos:update', (changes) => {
224224

225225
### Example: Incremental Updates
226226

227+
When the server returns computed fields (like server-generated IDs or timestamps), you can use the `onInsert` handler with `{ refetch: false }` to avoid unnecessary refetches while still syncing the server response:
228+
227229
```typescript
228-
// Handle server responses after mutations without full refetch
229-
const createTodo = async (todo) => {
230-
// Optimistically add the todo
231-
const tempId = crypto.randomUUID()
232-
todosCollection.insert({ ...todo, id: tempId })
233-
234-
try {
235-
// Send to server
236-
const serverTodo = await api.createTodo(todo)
237-
238-
// Sync the server response (with server-generated ID and timestamps)
239-
// without triggering a full collection refetch
240-
todosCollection.utils.writeBatch(() => {
241-
todosCollection.utils.writeDelete(tempId)
242-
todosCollection.utils.writeInsert(serverTodo)
243-
})
244-
} catch (error) {
245-
// Rollback happens automatically
246-
throw error
247-
}
248-
}
230+
const todosCollection = createCollection(
231+
queryCollectionOptions({
232+
queryKey: ['todos'],
233+
queryFn: fetchTodos,
234+
queryClient,
235+
getKey: (item) => item.id,
236+
237+
onInsert: async ({ transaction }) => {
238+
const newItems = transaction.mutations.map(m => m.modified)
239+
240+
// Send to server and get back items with server-computed fields
241+
const serverItems = await api.createTodos(newItems)
242+
243+
// Sync server-computed fields (like server-generated IDs, timestamps, etc.)
244+
// to the collection's synced data store
245+
todosCollection.utils.writeBatch(() => {
246+
serverItems.forEach(serverItem => {
247+
todosCollection.utils.writeInsert(serverItem)
248+
})
249+
})
250+
251+
// Skip automatic refetch since we've already synced the server response
252+
// (optimistic state is automatically replaced when handler completes)
253+
return { refetch: false }
254+
},
255+
256+
onUpdate: async ({ transaction }) => {
257+
const updates = transaction.mutations.map(m => ({
258+
id: m.key,
259+
changes: m.changes
260+
}))
261+
const serverItems = await api.updateTodos(updates)
262+
263+
// Sync server-computed fields from the update response
264+
todosCollection.utils.writeBatch(() => {
265+
serverItems.forEach(serverItem => {
266+
todosCollection.utils.writeUpdate(serverItem)
267+
})
268+
})
269+
270+
return { refetch: false }
271+
}
272+
})
273+
)
274+
275+
// Usage is just like a regular collection
276+
todosCollection.insert({ text: 'Buy milk', completed: false })
249277
```
250278

251279
### Example: Large Dataset Pagination

0 commit comments

Comments
 (0)