有什么方法可以获取存储在api slice [RTK Query]中的所有响应吗?
Is there any way to fetch all the responses stored in api slice [RTK Query]?
这是returns基于页面
的数据的挂钩
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
谢谢
我认为大多数实现都使“无限滚动”问题过于复杂。
您可以通过退后一步并思考您真正需要什么来实现这一目标:
- 当前可见数据
- 我们滚动到的方向有一些额外的数据
因为我们很懒惰,不想跟踪我们滚动到哪个方向,所以假设
- 当前可见数据
- 两个方向都有一点额外的数据。
我们还假设查询 returns 的响应类似于
{
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 秒,用户可以快速向上滚动浏览许多页面而无需进一步请求 - 而且,可能永远不会再次滚动到的数据将从缓存中删除并在必要时重新获取。
您可以使用 queryFn
来 assemble 您已有的缓存结果。记得使用 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[];
}
这是returns基于页面
的数据的挂钩 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
谢谢
我认为大多数实现都使“无限滚动”问题过于复杂。 您可以通过退后一步并思考您真正需要什么来实现这一目标:
- 当前可见数据
- 我们滚动到的方向有一些额外的数据
因为我们很懒惰,不想跟踪我们滚动到哪个方向,所以假设
- 当前可见数据
- 两个方向都有一点额外的数据。
我们还假设查询 returns 的响应类似于
{
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 秒,用户可以快速向上滚动浏览许多页面而无需进一步请求 - 而且,可能永远不会再次滚动到的数据将从缓存中删除并在必要时重新获取。
您可以使用 queryFn
来 assemble 您已有的缓存结果。记得使用 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[];
}