我使用相同的 Redux-Toolkit 查询,但使用不同的参数同时渲染两个不同的组件

问题描述 投票:0回答:1

我有一个轮播组件,它使用 Redux-Toolkit Query (RTKQ) 获取 8 个项目,而侧边栏上的另一个组件也使用 RTKQ 获取 3 个项目。它们同时渲染,并且使用相同的 RTKQ,有时,存在一个错误,使它们共享相同数量的项目(虽然它们不应该)

他们都使用这个查询。

const { data } = useGetPopularClipsQuery({ limit: 3, page: 1 });
const { data } = useGetPopularClipsQuery({ limit: 8, page: 0 });

RTKQ

getPopularClips: builder.query<
  { posts: Array<Post>; hasMore: boolean },
  { limit?: number; page: number }
>({
  providesTags: ['PopularClips'],
  query: ({ limit = 5, page }) => ({
    url: `/post/popular-clips`,
    params: {
      limit,
      page
    }
  }),
  transformResponse(baseQueryReturnValue: Post[], meta, arg) {
    return {
      posts: baseQueryReturnValue.map((clip) => ({
        ...clip,
        ...arg,
        fromQuery: `getPopularClips`
      })),
      hasMore: baseQueryReturnValue.length > 0havr 
    };
  },
  serializeQueryArgs: ({ endpointName }) => endpointName,
  merge: (currentCache, newItems) => ({
    posts: uniqBy(
      [...currentCache.posts, ...newItems.posts],
      (clip) => clip.id
    ),
    hasMore: newItems.posts.length > 0
  }),
  forceRefetch: ({ currentArg, previousArg }) =>
    currentArg?.page !== previousArg?.page
}),

两个组件必须同时渲染,但它们应该具有不同数量的项目。

reactjs typescript redux-toolkit rtk-query
1个回答
0
投票

您对所有订阅使用相同的查询缓存键,即端点名称。

serializeQueryArgs: ({ endpointName }) => endpointName,

通常,您指定

serializeQueryArgs
并让
defaultSerializeQueryArgs
函数处理它,这会创建一个缓存键,该键是端点名称和查询参数的字符串化版本的组合。

serializeQueryArgs
端点删除
getPopularClips
将允许使用
page
limit
参数创建缓存条目。如果两个(或任何重复的)参数集在两个或多个钩子调用中使用,那么它们仍然共享一个缓存条目,因为缓存键将解析为相同。

如果由于某种原因您仍然希望单独缓存具有重复查询参数的单独查询挂钩,那么我建议添加另一个参数。

示例:

getPopularClips: builder.query<
  { posts: Array<Post>; hasMore: boolean },
  { id?: string; limit?: number; page: number }
>({
  providesTags: ['PopularClips'],
  query: ({ limit = 5, page }) => ({
    url: `/post/popular-clips`,
    params: {
      limit,
      page
    }
  }),
  transformResponse(baseQueryReturnValue: Post[], meta, arg) {
    return {
      posts: baseQueryReturnValue.map((clip) => ({
        ...clip,
        ...arg,
        fromQuery: `getPopularClips`
      })),
      hasMore: baseQueryReturnValue.length > 0havr 
    };
  },
  merge: (currentCache, newItems) => ({
    posts: uniqBy(
      [...currentCache.posts, ...newItems.posts],
      (clip) => clip.id
    ),
    hasMore: newItems.posts.length > 0
  }),
  forceRefetch: ({ currentArg, previousArg }) =>
    currentArg?.page !== previousArg?.page
}),
const { data } = useGetPopularClipsQuery({ id: "hook1", limit: 3, page: 1 });
const { data } = useGetPopularClipsQuery({ id: "hook2", limit: 3, page: 1 });
© www.soinside.com 2019 - 2024. All rights reserved.