react 如何实现滚动加载
滚动加载的实现方法
在React中实现滚动加载通常需要监听滚动事件,判断用户是否滚动到页面底部附近,然后触发数据加载。以下是几种常见的方法:
使用Intersection Observer API
Intersection Observer API是现代浏览器提供的性能更好的滚动监听方式,相比传统滚动事件性能更优。

import React, { useState, useEffect, useRef } from 'react';
function ScrollLoad() {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
const observerRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting && !loading) {
loadMoreItems();
}
},
{ threshold: 1.0 }
);
if (observerRef.current) {
observer.observe(observerRef.current);
}
return () => {
if (observerRef.current) {
observer.unobserve(observerRef.current);
}
};
}, [loading]);
const loadMoreItems = async () => {
setLoading(true);
// 模拟API调用
const newItems = await fetchData(page);
setItems([...items, ...newItems]);
setPage(page + 1);
setLoading(false);
};
return (
<div>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
<div ref={observerRef}>
{loading && <div>Loading...</div>}
</div>
</div>
);
}
使用传统滚动事件监听
这种方法兼容性更好,但性能略差于Intersection Observer。

import React, { useState, useEffect } from 'react';
function ScrollLoad() {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [loading]);
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop !==
document.documentElement.offsetHeight ||
loading
) {
return;
}
loadMoreItems();
};
const loadMoreItems = async () => {
setLoading(true);
// 模拟API调用
const newItems = await fetchData(page);
setItems([...items, ...newItems]);
setPage(page + 1);
setLoading(false);
};
return (
<div>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
{loading && <div>Loading...</div>}
</div>
);
}
使用第三方库
一些流行的React库如react-infinite-scroll-component可以简化实现:
import InfiniteScroll from 'react-infinite-scroll-component';
function ScrollLoad() {
const [items, setItems] = useState([]);
const [hasMore, setHasMore] = useState(true);
const [page, setPage] = useState(1);
const fetchMoreData = async () => {
// 模拟API调用
const newItems = await fetchData(page);
setItems([...items, ...newItems]);
setPage(page + 1);
if (newItems.length === 0) {
setHasMore(false);
}
};
return (
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={hasMore}
loader={<h4>Loading...</h4>}
>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
</InfiniteScroll>
);
}
性能优化建议
实现滚动加载时应注意性能优化,避免不必要的渲染和计算。
- 使用React.memo或useMemo优化列表项渲染
- 节流滚动事件处理函数
- 考虑虚拟化长列表(react-window或react-virtualized)
- 在卸载组件时清除事件监听器
以上方法可以根据项目需求和浏览器兼容性要求选择适合的实现方式。






