react 如何实现滚动加载
实现滚动加载的基本原理
滚动加载(Infinite Scroll)通过监听滚动事件,在用户滚动到页面底部时触发数据加载。React中可以通过结合useEffect和useRef等Hook实现。
监听滚动事件
在组件中监听滚动事件,判断是否滚动到容器底部。通常需要计算容器的滚动高度、可视高度和滚动位置。

const containerRef = useRef(null);
useEffect(() => {
const handleScroll = () => {
if (containerRef.current) {
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
if (scrollTop + clientHeight >= scrollHeight - 10) {
loadMoreData();
}
}
};
const container = containerRef.current;
container.addEventListener('scroll', handleScroll);
return () => container.removeEventListener('scroll', handleScroll);
}, [loadMoreData]);
数据加载逻辑
定义异步函数加载更多数据,通常通过API请求获取新数据并合并到现有列表中。

const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
const loadMoreData = useCallback(async () => {
if (loading) return;
setLoading(true);
try {
const newData = await fetchData(page);
setData(prev => [...prev, ...newData]);
setPage(prev => prev + 1);
} catch (error) {
console.error('Error loading data:', error);
} finally {
setLoading(false);
}
}, [page, loading]);
优化滚动性能
使用防抖(debounce)或节流(throttle)避免频繁触发滚动事件。lodash库提供了现成的工具函数。
import { throttle } from 'lodash';
const handleScroll = throttle(() => {
// 滚动判断逻辑
}, 200);
使用Intersection Observer API
现代浏览器支持IntersectionObserver,性能优于传统滚动事件监听。创建一个观察器监控底部元素是否进入视口。
useEffect(() => {
const observer = new IntersectionObserver(
entries => {
if (entries[0].isIntersecting) {
loadMoreData();
}
},
{ threshold: 1.0 }
);
if (bottomRef.current) {
observer.observe(bottomRef.current);
}
return () => {
if (bottomRef.current) {
observer.unobserve(bottomRef.current);
}
};
}, [loadMoreData]);
注意事项
- 确保在组件卸载时清除事件监听或观察器,避免内存泄漏。
- 处理加载状态和错误状态,提供用户反馈(如加载指示器)。
- 对于大量数据,考虑虚拟滚动(如
react-window)优化渲染性能。






