使用 rtk 查询的过滤器和乐观更新的无限滚动

Infinite scrolling with filters and optimistic updates using rtk query

提问人:nick13name37 提问时间:11/4/2023 最后编辑:nick13name37 更新时间:11/4/2023 访问量:41

问:

我正在使用 rtk 查询并有一个无限滚动的实现,这个逻辑是通过偏移量和限制量实现的,但是我也有过滤器,当更改任何过滤器时,我必须将偏移量重置为 0。

useEffect(() => {
    setCurrentOffset(0)
}, [status, filter])

我使用 merge、serializeQueryArgs 和 forceRefetch。对于serializeQueryArgs,我使用此查询的参数,不包括偏移量,因此当任何过滤器更改时,我都会获得缓存更新

getShopProducts: build.query<IResponseShopProductData, Partial<IQueryParams>>({
            query: queryParams => {
                const queryString = createQueryParamString(queryParams)
                return `shop-products?${queryString}`
            },
            serializeQueryArgs: ({ queryArgs }) => {
                const newQueryArgs = { ...queryArgs }

                if (newQueryArgs.offset) {
                    delete newQueryArgs.offset
                }

                return queryArgs
            },

            merge: (currentCache, newItems, { arg }) => {
                if (currentCache.results && arg.offset !== 0) {
                    return {
                        ...currentCache,
                        ...newItems,
                        results: [...currentCache.results, ...newItems.results]
                    }
                }

                return newItems
            },
            forceRefetch({ currentArg, previousArg }) {
                return currentArg !== previousArg
            },
            providesTags: result =>
                result
                    ? [
                            ...result.results.map(({ id }) => ({
                                type: 'ShopProducts' as const,
                                id
                            })),
                            'ShopProducts'
                      ]
                    : ['ShopProducts']
})

我还使用乐观更新,因为我显示的数据包含添加到收藏夹的逻辑,我希望用户立即看到结果,而无需重新加载整个列表并重置过滤器

addWishList: build.mutation<void, IAddWishListData>({
            query: data => ({
                url: `wish-list/`,
                method: 'POST',
                body: data
            }),
            async onQueryStarted({ shop_product }, { dispatch, queryFulfilled }) {
                const patchResult = dispatch(
                    shopProducts.util.updateQueryData('getShopProducts', {}, draft => {
                        const shopProduct = draft.results.find(item => item.id === shop_product)
                        if (shopProduct) shopProduct.in_wish_list = true
                    })
                )

                try {
                    await queryFulfilled
                } catch {
                    patchResult.undo()
                }
            }
})

我在两种方法之间遇到了冲突,因为当我将查询参数设置为缓存的键时,键会动态更改并且乐观更新不起作用。

相反,如果我对缓存使用静态键(如 endpointName),则在更改过滤器时重置缓存将不起作用

serializeQueryArgs: ({ endpointName }) => {
    return endpointName
},

问题是是否有可能做我想做的事,如果可以,应该注意什么?

reactjs 无限滚动 rtk-query optimistic-ui

评论


答: 暂无答案