Skip to content

Commit a1ed746

Browse files
committed
fix(shop): isMutating check === 1 per TkDodo's concurrent pattern
At onSettled time, React Query v5 still counts the current mutation as in-flight. The check should be === 1 ("I'm the only one left"), not === 0 ("everyone has finished"). Also returns the invalidation promise so the mutation stays isPending until the background refetch finishes. Reference: tkdodo.eu/blog/concurrent-optimistic-updates-in-react-query
1 parent d52afbd commit a1ed746

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

src/hooks/useCart.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,18 @@ const CART_MUTATION_KEY = ['shopify', 'cart', 'mutate'] as const
3434
* earlier optimistic writes) and layers its own change on top. When the
3535
* last mutation settles, the refetch reconciles everything with the
3636
* server's final truth.
37+
*
38+
* Returns the invalidation promise so the mutation stays in `isPending`
39+
* until the background refetch completes (per TkDodo's recommendation).
40+
*
41+
* @see https://tkdodo.eu/blog/concurrent-optimistic-updates-in-react-query
3742
*/
3843
function settleWhenIdle(qc: ReturnType<typeof useQueryClient>) {
3944
// isMutating counts mutations that haven't settled yet. At the time
40-
// onSettled fires, the *current* mutation has already decremented, so
41-
// 0 means "I was the last one."
42-
if (qc.isMutating({ mutationKey: CART_MUTATION_KEY }) === 0) {
43-
qc.invalidateQueries({ queryKey: CART_QUERY_KEY })
45+
// onSettled fires, the *current* mutation is still counted, so
46+
// 1 means "I'm the last one in flight."
47+
if (qc.isMutating({ mutationKey: CART_MUTATION_KEY }) === 1) {
48+
return qc.invalidateQueries({ queryKey: CART_QUERY_KEY })
4449
}
4550
}
4651

0 commit comments

Comments
 (0)