我有一个组件,它是一个使用Redux—Toolkit Query(RTKQ)获取8个项目的 carousel ,另一个在侧边栏上的组件,它也使用RTKQ获取3个项目.它们都在同一时间呈现,并且使用相同的RTKQ,有时候,有一个bug,使它们共享相同数量的项目(虽然它们不应该)

他们都使用这个查询.

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

两个组件必须同时呈现,但它们应该具有不同数量的项目.

推荐答案

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

serializeQueryArgs: ({ endpointName }) => endpointName,

通常,not指定serializeQueryArgs并让defaultSerializeQueryArgs函数处理它,这将创建一个缓存键,该键是端点名称和查询args的字符串化版本的组合.

getPopularClips端点移除serializeQueryArgs将允许使用pagelimit参数创建缓存条目.如果两个(or any duplicate)参数集跨两个或多个钩子调用使用,则它们would仍然共享高速缓存条目,因为高速缓存键将解析为相同.

如果出于某种原因,您仍然希望单独的查询挂钩与重复的查询参数被缓存,那么我建议在查询调用100中添加参数.

示例:

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 });

Typescript相关问答推荐

类型脚本不会推断键的值类型

等待的R没有用响应对象展开到R

界面中这种类型的界面界面中的多态性

在类型内部使用泛型类型时,不能使用其他字符串索引

如果一个变量不是never类型,我如何创建编译器错误?

数组文字中对象的从键开始枚举

部分类型化非 struct 化对象参数

刷新页面时,TypeScrip Redux丢失状态

避免混淆两种不同的ID类型

三重融合视角与正交阵

如何在TypeScrip中使用数组作为字符串的封闭列表?

更漂亮的格式数组<;T>;到T[]

传入类型参数<;T>;变容函数

如何使用 Angular 确定给定值是否与应用程序中特定单选按钮的值匹配?

带有 Select 器和映射器的Typescript 泛型

如何强制对象数组中的对象属性具有非空字符串值?

React 中如何比较两个对象数组并获取不同的值?

使用react+ts通过props传递数据

typeof 运算符和泛型的奇怪行为

如何在故事书的Typescript 中编写decorator ?