在React中,有很多npm包可以用来实现无限滚动,但创建和使用我们自己的无限滚动真的很有趣。 实现自创无限滚动的最好的部分是,我们可以按照我们想要的方式来定制它。
所以,让我们开始这个旅程吧。
需要
无限滚动允许用户在看不到终点的情况下滚动浏览数据列表。 我们可以在滚动时加入分页功能,即(逐块获取数据)来提高网站的性能。
在React中的实现
要实现无限滚动,我们首先要知道当前列表的最后一个元素。 为了得到它,我们可以从onScroll 方法中得到帮助,并在react useRef中保存我们的引用。
下面的代码将给我们一个关于实现onScroll 方法和使用ref的概念。
首先,让我们导入useRef。
const listInnerRef = useRef();
在列表的wrapper div中使用相同的ref。
<div
onScroll={onScroll}
ref={listInnerRef}
>
<!-- List Items -->
</div>
为了检测最后一个元素,我们应该创建一个onScroll 方法,如下所示。
const onScroll = () => {
if (listInnerRef.current) {
const { scrollTop, scrollHeight, clientHeight } = listInnerRef.current;
if (scrollTop + clientHeight === scrollHeight) {
// This will be triggered after hitting the last element.
// API call should be made here while implementing pagination.
}
}
};
在无限滚动中添加分页功能
const [currPage, setCurrPage] = useState(1); // storing current page number
const [prevPage, setPrevPage] = useState(0); // storing prev page number
const [userList, setUserList] = useState([]); // storing list
const [wasLastList, setWasLastList] = useState(false); // setting a flag to know the last list
为了获取列表,我们将从假的API中获取帮助。
const response = await axios.get(
`https://api.instantwebtools.net/v1/passenger?page=${currPage}&size=10`
);
要知道响应列表是否为空,我们将使用以下代码
if (!response.data.data.length) {
setWasLastList(true);
}
如果列表不是空的,我们将把响应列表添加到当前列表中。
setPrevPage(currPage);
setUserList([...userList, ...response.data.data]);
保持这一切的使用效果将看起来像这样。
useEffect(() => {
const fetchData = async () => {
const response = await axios.get(
`https://api.instantwebtools.net/v1/passenger?page=${currPage}&size=10`
);
if (!response.data.data.length) {
setWasLastList(true);
return;
}
setPrevPage(currPage);
setUserList([...userList, ...response.data.data]);
};
if (!wasLastList && prevPage !== currPage) {
fetchData();
}
}, [currPage, wasLastList, prevPage, userList]);

就这样,我们完成了在我们的react应用中实现自定义无限滚动分页的工作。
关于完整的代码参考,请点击链接react-custom-infinite-scroll-with-pagination。
优势
-
自定义无限滚动与分页确实提高了网站的性能。
-
虽然这不是一个npm包,但我们不需要实现任何第三方库,可以根据我们的需要进行定制。