RTK查询| Redux 工具包 | React 中的无限滚动 |缓存行为 |以前的数据不会根据类别更改而重置

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

我有 3 个类别的 3 个按钮,它们是 1.查看所有 2.手机 3.笔记本电脑,当单击每个类别时,它会加载与之相关的列表,而且我正在尝试实现 分页。 我正在使用 React 和 Redux 工具包/RTK 查询。

以下是使用状态及查询

const [currentPage, setCurrentPage] = useState(1);

const [category, setCategory] = useState('all');

  const {
    data ,
    isLoading,
    isFetching ,
    error
  } = useCategorySearchAPIQuery(
    {groupBy: selectedCategory, page: currentPage},
    {refetchOnMountOrArgChange: true},
  );

下面是构建器查询,其中 groupBy 是所选类别

  categorySearchAPI: builder.query({
      query: ({groupBy, page}) => ({
        url: `${CATEGORY_ENDPOINT}/all?group_by=${groupBy}&page=${page}`,
      }),
      transformResponse: (response, meta, arg) => {
        return response.data;
      },
      serializeQueryArgs: ({endpointName}) => {
        return endpointName;
      },
      // Always merge incoming data to the cache entry
      merge: (currentCache, newItems) => {
        currentCache.push(...newItems);
      },
      // Refetch when the page arg changes
      forceRefetch({currentArg, previousArg}) {
        return currentArg !== previousArg;
      },
    }),

所需的流程是,当单击类别按钮时,它应该仅显示单击的类别,并且当滚动时,它应该加载该类别的下一页。当类别更改时,会使用新数据重置缓存。

当前当类别更改时 - 数据不会重置并且会混合(类别会混合)。我需要在类别更改时重置并在滚动时增加页面。

在搜索解决方案后发现此代码设置但无法使其按预期工作。这里出了什么问题。

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

要轻松解决此问题,您必须在

category
中包含
serializeQueryArgs
参数:

serializeQueryArgs: ({
  endpointName,
  queryArgs,
  endpointDefinition,
}) => {
   const { groupBy } = queryArgs;
   return defaultSerializeQueryArgs({
       endpointName,
       queryArgs: { groupBy },
       endpointDefinition,
   });
},

这会为每个类别创建一个缓存,因为

category
现在是缓存键定义的一部分。因此从技术上讲,您不会重置缓存数据,而是会更改您指向的缓存。然后如果用户快速按下之前的类别,数据就会在那里。

建议:
  1. 使用

    forceRefetch
    refetchOnMountOrArgChange
    ,因为您正在重复代码。

  2. 使用乐观更新

    updateQueryData
    以防您删除/更新缓存中的对象。

  3. 在这里你有一个很好的

    merge
    功能:

export function mergeData<T extends ListResponseTypes>(
  currentCacheData: BaseListResponseFor<T>,
  responseData: BaseListResponseFor<T>,
  customOrder: boolean | undefined = false
) {
  if (responseData?.pagination?.prev_page && responseData?.items?.length <= 0) {
    return currentCacheData;
  }

  if (
    isNil(responseData?.pagination?.prev_page) &&
    isNil(responseData?.pagination?.next_page)
  ) {
    return { pagination: responseData?.pagination, items: responseData?.items };
  }

  // Create a map for efficient lookups of existing entities
  const currentDataMap = new Map<number, T>();

  // Populate the map with existing entities based on their IDs
  for (const entity of currentCacheData.items) {
    currentDataMap.set(entity.id, entity);
  }

  // Iterate through each entity in the new data https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set
  for (const newEntity of responseData.items) {
    currentDataMap.set(newEntity.id, newEntity);
  }

  // Create a new array to store the result
  const updatedData = customOrder
    ? [...currentDataMap.values()]
    : [...currentDataMap.values()]?.sort(
        (a, b) =>
          new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
      );

  return { pagination: responseData?.pagination, items: updatedData };
}
© www.soinside.com 2019 - 2024. All rights reserved.