问题描述
我正在使用 SWR to fetch data as stated in the docs:
function App () {
const [pageIndex,setPageIndex] = useState(0);
// The API URL includes the page index,which is a React state.
const { data } = useSWR(`/api/data?page=${pageIndex}`,fetcher);
// ... handle loading and error states
return <div>
{data.map(item => <div key={item.id}>{item.name}</div>)}
<button onClick={() => setPageIndex(pageIndex - 1)}>PrevIoUs</button>
<button onClick={() => setPageIndex(pageIndex + 1)}>Next</button>
</div>
}
我的情况唯一的区别是我在同一页面上加载了更多项目(所以更像是无限滚动而不是分页),但问题是:
const { data } = useSWR(`/api/data?page=${pageIndex}`,fetcher);
注意如何根据来自状态的 pageIndex
变量获取数据。一旦它改变了一切重新渲染,而不是每次用户点击按钮时获得更多项目,我总是得到刷新,然后用户看到初始渲染,然后是新项目。所以简而言之,我想在页面底部加载更多项目,而不是刷新所有内容然后添加项目......我错过了什么?有 useSWRInfinite,但它是相同的故事,它从状态中获取 url 数据...
解决方法
我会将之前获取的所有页面缓存在本地状态。使用依赖于 useEffect
状态和当前 pageIndex
值的 data
钩子,将数据存储在使用当前 pageIndex
作为键的对象中。渲染所有获取的页面时,将 pages
值数组展平为单个可渲染数组。
function App () {
const [pageIndex,setPageIndex] = useState(0);
const [pages,setPages] = useState({});
// The API URL includes the page index,which is a React state.
const { data } = useSWR(`/api/data?page=${pageIndex}`,fetcher);
useEffect(() => {
// cache page in state
setPages(pages => ({
[pageIndex]: data,}));
},[data,pageIndex]);
// ... handle loading and error states
// NOTE: pages is an object of arrays,so flatten values to single array to render
return <div>
{Object.values(pages).flatten().map(item => (
<div key={item.id}>{item.name}</div>
))}
<button onClick={() => setPageIndex(page => page - 1)}>Previous</button>
<button onClick={() => setPageIndex(page => page + 1)}>Next</button>
</div>
}