Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,11 @@ Transactional mutators allow you to batch and stage local changes across collect

Mutators are created with a `mutationFn`. You can define a single, generic `mutationFn` for your whole app. Or you can define collection or mutation specific functions.

The `mutationFn` is responsible for handling the local changes and processing them, usually to send them to a server or database to be stored, e.g.:
The `mutationFn` is responsible for handling the local changes and processing them, usually to send them to a server or database to be stored.

**Important:** Inside your `mutationFn`, you must ensure that your server writes have synced back before you return, as the optimistic state is dropped when you return from the mutation function. You generally use collection-specific helpers to do this, such as Query's `utils.refetch()`, direct write APIs, or Electric's `utils.awaitTxId()`.

For example:

```tsx
import type { MutationFn } from "@tanstack/react-db"
Expand Down Expand Up @@ -556,13 +560,19 @@ const addTodo = createOptimisticAction<string>({
completed: false,
})
},
mutationFn: async (text) => {
mutationFn: async (text, params) => {
// Persist the todo to your backend
const response = await fetch("/api/todos", {
method: "POST",
body: JSON.stringify({ text, completed: false }),
})
return response.json()
const result = await response.json()

// IMPORTANT: Ensure server writes have synced back before returning
// This ensures the optimistic state can be safely discarded
await todoCollection.utils.refetch()

return result
},
})

Expand Down
13 changes: 12 additions & 1 deletion packages/db/src/optimistic-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import type { CreateOptimisticActionsOptions, Transaction } from "./types"
* The optimistic update is applied via the `onMutate` callback, and the server mutation
* is executed via the `mutationFn`.
*
* **Important:** Inside your `mutationFn`, you must ensure that your server writes have synced back
* before you return, as the optimistic state is dropped when you return from the mutation function.
* You generally use collection-specific helpers to do this, such as Query's `utils.refetch()`,
* direct write APIs, or Electric's `utils.awaitTxId()`.
*
* @example
* ```ts
* const addTodo = createOptimisticAction<string>({
Expand All @@ -26,7 +31,13 @@ import type { CreateOptimisticActionsOptions, Transaction } from "./types"
* method: 'POST',
* body: JSON.stringify({ text, completed: false }),
* })
* return response.json()
* const result = await response.json()
*
* // IMPORTANT: Ensure server writes have synced back before returning
* // This ensures the optimistic state can be safely discarded
* await todoCollection.utils.refetch()
*
* return result
* }
* })
*
Expand Down
Loading