react滚动分页插件如何做
实现React滚动分页的常用方法
使用Intersection Observer API监听滚动 在React组件中创建一个IntersectionObserver实例,观察页面底部的"哨兵"元素。当哨兵进入视口时触发数据加载。这种方法不需要手动计算滚动位置,性能较好。
import { useRef, useEffect, useState } from 'react';
function InfiniteScroll({ fetchData }) {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
const observerRef = useRef(null);
const loadingRef = useRef(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !loadingRef.current) {
loadingRef.current = true;
fetchData(page).then(newItems => {
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
loadingRef.current = false;
});
}
},
{ threshold: 1.0 }
);
if (observerRef.current) {
observer.observe(observerRef.current);
}
return () => observer.disconnect();
}, [page, fetchData]);
return (
<div>
{items.map(item => (
<div key={item.id}>{item.content}</div>
))}
<div ref={observerRef} style={{ height: '20px' }} />
</div>
);
}
使用第三方库react-infinite-scroll-component 这个流行库提供了开箱即用的解决方案,简化了实现过程:
import InfiniteScroll from 'react-infinite-scroll-component';
function ScrollPagination({ items, fetchMoreData, hasMore }) {
return (
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={hasMore}
loader={<h4>Loading...</h4>}
endMessage={<p>No more data</p>}
>
{items.map((item) => (
<div key={item.id}>{item.content}</div>
))}
</InfiniteScroll>
);
}
自定义滚动事件处理 对于需要更多控制的情况,可以监听滚动事件并计算位置:
useEffect(() => {
const handleScroll = () => {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 100 && !loadingRef.current) {
loadingRef.current = true;
fetchData(page).then(newItems => {
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
loadingRef.current = false;
});
}
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [page, fetchData]);
性能优化要点
添加防抖机制避免频繁触发滚动事件,对于快速滚动特别重要:
const debouncedHandleScroll = debounce(handleScroll, 200);
window.addEventListener('scroll', debouncedHandleScroll);
确保为列表项添加稳定的key,避免重新渲染整个列表。考虑使用虚拟滚动技术(如react-window)处理超长列表。
错误处理和边界条件
实现加载状态指示器和错误处理机制。当数据加载完毕时显示提示信息,避免持续请求。处理API错误情况,允许用户重试加载。
const [error, setError] = useState(null);
const [hasMore, setHasMore] = useState(true);
// 在数据加载函数中
fetchData(page)
.then(newItems => {
if (newItems.length === 0) setHasMore(false);
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
})
.catch(err => setError(err.message))
.finally(() => loadingRef.current = false);






