'use client'; import { useCallback, useEffect, useRef, useState } from 'react'; import { api } from './api'; import type { CursorPage } from './types'; /** * 游标分页列表 hook(对接后端 CursorPage)。 * filters 变化自动重载第一页;loadMore 追加下一页;reload 重置(写操作后刷新)。 */ export function useCursorList(url: string, filters: Record, limit = 20) { const [items, setItems] = useState([]); const [nextCursor, setNextCursor] = useState(null); const [loading, setLoading] = useState(false); const requestSeq = useRef(0); const filtersKey = JSON.stringify(filters); const load = useCallback( async (cursor: number | null) => { const seq = requestSeq.current + 1; requestSeq.current = seq; setLoading(true); try { const params: Record = { ...JSON.parse(filtersKey), limit }; if (cursor != null) params.cursor = cursor; const { data } = await api.get>(url, { params }); if (requestSeq.current !== seq) return; setItems((prev) => (cursor == null ? data.items : [...prev, ...data.items])); setNextCursor(data.next_cursor); } finally { if (requestSeq.current === seq) setLoading(false); } }, [url, filtersKey, limit], ); useEffect(() => { setItems([]); setNextCursor(null); load(null); }, [load]); return { items, nextCursor, loading, loadMore: () => load(nextCursor), reload: () => load(null), }; }