import { useSWRConfig } from "swr"; import useSWRInfinite from "swr/infinite"; export type TResponseData = { data: D nextId?: string totalCount?: null | number pageIndex?: number pageSize?: number } export const createKey = (query: string, pageSize: number = 10, extra: Record = []) => { return (pageIndex: number, previousPageData) => { // pageIndex 后端要求是从 1 开始 if (pageIndex === 0) return [ query, { nextId: undefined, pageSize, pageIndex: pageIndex + 1 }, extra, ]; // 如果是以 pageIndex 作为分页依据, 即有pageIndex 且 没有 nextId // if (previousPageData && previousPageData.pageIndex && !previousPageData.nextId) { return [ query, { pageSize, pageIndex: previousPageData.pageIndex + 1 }, extra, ]; } if (previousPageData && previousPageData.nextId) { return [ query, { pageSize, nextId: previousPageData.nextId}, extra, ]; } return null; }; } export const useLoadMoreInfinite = (getKey, fetcher, params = {}) => { const {cache} = useSWRConfig() const { data, setSize, size, mutate, isLoading, error } = useSWRInfinite<{ data: T nextId?: string totalCount?: null | number pageIndex?: number pageSize?: number }>(getKey, fetcher, { ...params, revalidateIfStale: false, revalidateFirstPage: false, onErrorRetry(err, key, config, revalidate, revalidateOpts) { if (err.code === 404) return if (err.code === 401) { // 获取所有缓存的 key(SWR 缓存基于 key 存储) const allKeys = Array.from(cache.keys()); // 过滤出当前分页请求相关的 key(如包含 /api/list?page=) const relevantKeys = allKeys.filter(_key => _key.includes(key)); // 逐个删除这些 key 的缓存 relevantKeys.forEach(key => cache.delete(key)); return } if (revalidateOpts.retryCount >= 3) return }, }); // 扁平化后的数据列表 const list = (data?.flatMap((page) => page?.data || []) || []) as T; // 原分页数据二维数组 const pages = data const pageIndex = size const loadMore = () => { setSize((size) => size + 1); } return { data, list, pageIndex, isLoading, pages, mutate, setSize, loadMore, error, } }