Prompt
When using async/concurrent flows (streaming, dehydration/rehydration, optimistic updates), ensure you never persist “in-flight” async state and you always return promises from async callbacks.
1) Don’t persist promises during streaming/dehydration
- If a query might still be pending, configuring persistence to store only settled/resolved outcomes prevents serialization issues when pending work is dehydrated and streamed.
<PersistQueryClientProvider
client={queryClient}
persistOptions={{
persister,
// Persist only queries that have resolved (not pending promises)
dehydrateOptions: { shouldDehydrateQuery: defaultShouldDehydrateQuery },
}}
>
{children}
</PersistQueryClientProvider>
2) Don’t drop promise lifecycles in concurrency callbacks
- For concurrency-related callback hooks (e.g., mutation lifecycle handlers) that trigger async work, write them in a way that returns the promise (consistent concise arrow syntax is preferred).
useMutation({
onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
});
Practical checklist:
- Any persistence/dehydration layer: allow only resolved/errored (settled) query results to be stored.
- Any callback that triggers async operations: return the promise so downstream orchestration/lifecycle expectations remain correct.