React查询乐观更新导致闪烁更新

发布于 2025-01-31 11:58:56 字数 1584 浏览 4 评论 0原文

我对React查询有一个问题,如果用户按按钮太快按下按钮,触发突变,即使返回API调用,正确的值也会在屏幕上闪烁并更改,即使在尝试取消它们时也会返回API调用。我注意到此问题也发生在官方React查询示例以进行乐观更新。这是 fivese 我 我对那里发生了问题。

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')
            },
        }
    )
}

我正在考虑拒绝使用UsiseIncreaseCount的电话,但是随后onMutate将被拒绝,我不想要。理想情况下,仅将拒绝API电话。 React查询中是否内置了内置的方式?

I'm having an issue with React Query where if a user presses a button too fast, triggering a mutation, the correct value flashes and changes on the screen as the API calls are returned, even when attempting to cancel them. I notice this problem also happens in the official React Query example for optimistic updates. Here's a video I took of the problem happening there.

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')
            },
        }
    )
}

I'm thinking of debouncing the call to use useIncreaseCount, but then onMutate will get debounced, and I don't want that. Ideally just the API call would be debounced. Is there a built in way in React Query to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰雪之触 2025-02-07 11:58:56

问题来自以下事实:即使该突变的不同调用仍在运行,每个onsuccess回调 queryclient.invalidatequeries 即使。不执行此操作是用户代码的责任。我看到两种方法:

  • 有时我们要做的一件事是用ref跟踪正在进行的突变量(inmutate inmutate ,insettled ),然后仅调用queryclient.invalidatequeries如果计数器为零。
  • 分配突变键并使用!queryClient.ismutating(key)也应起作用。

The problem come from the fact that every onSuccess callback calls queryClient.invalidateQueries, even though a different invocation of the mutation is still running. It's the responsibility of the user code to not do that. I see two ways:

  • One thing we are doing sometimes is to track the amount of ongoing mutations with a ref (increment in onMutate, decrement in onSettled), then only call queryClient.invalidateQueries if the counter is zero.
  • assigning mutationKeys and using !queryClient.isMutating(key) should also work.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文