基于react-virtuoso实现双向滚动(上下)时获取新数据的方案
实现React Virtuoso双向无限滚动(向上/向下加载)
要实现向上滚动时加载更早的数据,需要利用Virtuoso的startReached事件(对应滚动到顶部的触发),同时调整分页逻辑和数据插入方式,具体改动如下:
核心改动点
- 新增两个分页状态:
currentEndPage(跟踪向下加载的页码)、currentStartPage(跟踪向上加载的页码) - 新增加载锁
isLoading,避免滚动时重复触发请求 - 使用
startReached监听顶部滚动事件,触发向上加载,数据插入到数组头部 - 保留
endReached的向下加载逻辑,数据追加到数组尾部
修改后的完整代码
const App = () => { const [currentEndPage, setCurrentEndPage] = useState(1); const [currentStartPage, setCurrentStartPage] = useState(0); const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(false); const fetchData = async (direction) => { if (isLoading) return; setIsLoading(true); const targetPage = direction === 'down' ? currentEndPage : currentStartPage; try { const response = await fetch(`https://dummyapi.io/data/v1/user?limit=10&page=${targetPage}`); const result = await response.json(); if (result.data.length === 0) { // 无数据时停止继续请求 setIsLoading(false); return; } if (direction === 'down') { setData(prev => [...prev, ...result.data]); setCurrentEndPage(prev => prev + 1); } else { setData(prev => [...result.data, ...prev]); setCurrentStartPage(prev => prev - 1); } } catch (error) { console.log("error", error); } finally { setIsLoading(false); } }; return( <Virtuoso style={{ height: 1000 }} data={data} endReached={() => fetchData('down')} startReached={() => fetchData('up')} itemContent={(index, item) => { const bgColor = index % 2 === 0 ? "yellow" : "blue"; return ( <div style={{ background: bgColor }}> <div>{item.name}</div> </div> ); }} /> ); };
注意事项
- 请确认你的API支持页码递减请求(比如
page=0、page=-1是否有效),如果API页码从1开始且不支持小于1的值,需要调整currentStartPage初始值为1,并在请求前判断targetPage > 0再执行请求 - 当请求返回空数据时,自动停止后续同方向的加载,避免无效请求
内容的提问来源于stack exchange,提问作者shafa vp
相关产品推荐
相关产品推荐

