redux 是否有任何方法可以获取存储在api切片[RTK Query]中的所有响应?

mznpcxlj  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(117)

下面是一个钩子,它返回基于页面的数据

const {
        data,
        isFetching,
        isLoading,
        isError,
    } = useGetResourceQuery(page, perPage );

这是API

export const api = createApi({
        baseQuery: fetchBaseQuery({
            baseUrl: "http://localhost:3001",

        }),
        tagTypes: ["resource"],
        endpoints: (build) => ({
            getResource: build.query({
            query: (page = 1, perPage = 20) =>
                `resource?spage=${page}&limit=${perPage}`,
            }),
        }),
    });
    export const {useGetResourceQuery} = api

是否有任何方法可以提取所有查询的状态?我想实现基于滚动的分页(无限滚动)我们是否需要更新中间件?或者是否有任何方法可以访问状态并将其作为函数公开如上所述,我查看了文档,但没有找到解决方案
我可以使用本地状态并将它们连接起来,但想知道是否可以使用RTK
谢谢

0lvr5msh

0lvr5msh1#

我认为大多数实现都把“无限滚动”的问题复杂化了很多。你可以退一步考虑一下你真正需要什么来实现这个目标:

  • 当前视图内数据
  • 将一点额外的数据添加到我们要滚动的方向

因为我们很懒,不想跟踪我们滚动到的方向,所以假设

  • 当前视图内数据
  • 一点额外数据到两个方向

我们还假设查询返回如下响应

{
    offset: 50,
    items: [...]
  }

因此,假设一个页面足够大,可以包含一个屏幕的所有数据,我们将得到如下结果

const currentPage = // something calculated from ScrollPosition

const lastResult = usePageQuery(currentPage - 1, { skip: currentPage === 1 }) // don't fetch pages before 0
const currentResult = usePageQuery(currentPage)
const nextResult = usePageQuery(currentPage + 1)

const combined = useMemo(() => {
  const arr = new Array(pageSize * (currentPage + 1))
  for (const data of [lastResult.data, currentResult.data, nextResult.data]) {
    if (data) {
      arr.splice(data.offset, data.items.length, ...data.items)
    }
  }
  return arr
}, [pageSize, currentPage, lastResult.data, currentResult.data, nextResult.data])

// work with `combined` here

由于组件未引用的请求将在存储区中停留60秒,因此用户可以快速向上滚动许多页而无需进一步请求-而且,可能永远不会再次滚动到的数据将该高速缓存中删除,并在必要时重新获取。

wmvff8tz

wmvff8tz2#

您可以使用queryFn来组合您已经拥有的缓存结果。请记住使用invalidation来获取更新的状态。
在下面的代码中,第一个queryFn只是一个伪API,第二个端点是您正在寻找的解决方案:

export const songsApi = createApi({
  reducerPath: "songsApi",
  baseQuery: fetchBaseQuery(),
  endpoints: (builder) => ({
    getSongs: builder.query<Result<Song>, { offset: number; limit: number }>({
      queryFn: ({ offset, limit }) => {
        let list: Song[] = [];
        for (let i = offset; i < offset + limit; i++) {
          list.push({ id: i.toString(), name: `Song ${i}` });
        }
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve({
              data: {
                total: 100,
                list
              } as Result<Song>
            });
          }, 1000);
        });
      }
    }),

    getAllSongs: builder.query<Result<Song>, void>({
      queryFn: (_, { getState }) => {
        let state = getState();
        let songs: Song[] = [];
        for (let offset = 0; offset < 100; offset += 10) {
          const { data } = songsApi.endpoints.getSongs.select({
            offset,
            limit: 10
          })(state as any);
          if (data && data.list) {
            songs.push(...data!.list);
          }
        }
        return Promise.resolve({ data: { total: 100, list: songs as Song[] } });
      }
    })
  })
});

interface Result<T> {
  total: number;
  list: T[];
}

相关问题