Optimistic Updates
An optimistic update applies an immediate change to the cache before the server responds, so the UI feels instant. If the mutation succeeds, the server response replaces the optimistic value. If it fails, the optimistic value is rolled back automatically.
Pass optimisticResponse to mutate with the shape you expect back:
const [mutate, pending] = useMutation(graphql(` mutation ToggleLike($id: ID!) { toggleLike(id: $id) { id liked likeCount } }`))
await mutate({ variables: { id: postId }, optimisticResponse: { toggleLike: { id: postId, liked: true, likeCount: currentCount + 1 } }})The cache updates immediately and any components watching those fields re-render with no useState and no manual rollback logic.
Creating New Records
Sometimes it's not possible to know the ID to provide in an optimistic response. Most commonly, this happens when creating a new record and inserting the result into a list:
mutation CreateTodoItem($text: String!) { createItem(text: $text) { item { id # <--- what goes here? text ...All_Items_insert } }}To handle this, mark the id field with @optimisticKey and Houdini will generate a temporary ID for you:
mutation CreateTodoItem($text: String!) { createItem(text: $text) { item { id @optimisticKey text ...All_Items_insert } }}With @optimisticKey, you no longer need to provide an id in the optimisticResponse. Houdini generates one, immediately inserts the record into the list, and replaces the temporary ID with the real one when the mutation resolves.
The important distinction from making up your own ID is that Houdini tracks these generated keys internally. If you were to reference the generated key in another mutation before the create resolves (say, to mark the new item as complete), the second mutation will block until the real ID comes back from the server.
If your record's key is a custom scalar that Houdini can't generate, you'll need to supply the value manually in optimisticResponse.