React Query Optimistic Update 导致闪烁更新

React Query Optimistic Update causing flashing updates

我在使用 React Query 时遇到问题,如果用户按下按钮的速度太快,会触发突变,即使返回 API 调用,正确的值也会闪烁并在屏幕上发生变化试图取消它们。我注意到这个问题也发生在官方的 React 查询中 example for optimistic updates. Here's a video 我注意到了那里发生的问题。

export const useIncreaseCount = () => {
    const queryClient = useQueryClient()

    return useMutation(
        () => {
            const cart = queryClient.getQueryData('cart') as Cart

            return setCart(cart)
        },
        {
            onMutate: async (cartItemId: string) => {
                await queryClient.cancelQueries('cart')

                const previousCart = queryClient.getQueryData('cart') as Cart

                queryClient.setQueryData(
                    'cart',
                    increaseCount(previousCart, cartItemId)
                )

                return { previousCart }
            },
            onError: (error, _cartItem, context) => {
                console.log('error mutating cart', error)
                if (!context) return
                queryClient.setQueryData('cart', context.previousCart)
            },
            onSuccess: () => {
                queryClient.invalidateQueries('cart')
            },
        }
    )
}

我正在考虑对使用 useIncreaseCount 的调用去抖动,但是 onMutate 会被去抖动,我不希望这样。理想情况下,只有 API 调用会被去抖动。 React Query 中是否有内置的方式来执行此操作?

问题来自于每个 onSuccess 回调调用 queryClient.invalidateQueries,即使不同的突变调用仍然是 运行。用户代码有责任不这样做。我看到两种方式:

  • 我们有时做的一件事是用 ref 跟踪正在进行的突变的数量(在 onMutate 中递增,在 onSettled 中递减),然后只调用 queryClient.invalidateQueries 如果计数器为零。
  • 分配 mutationKeys 并使用 !queryClient.isMutating(key) 也应该有效。