需求: select的下拉框,后端做了分页,此时前段需要同步加分页
解决思路: 考虑到交互和性能,采用触底请求下一页(无限滚动加载)
代码示例:
import { Select, message } from 'antd';
import React, { useEffect, useState } from 'react';
const App: React.FC = () => {
const [selectArr, setSelectArr] = useState([]); //下拉框数组
const [loading, setLoading] = useState(false); //加载loading
const [hasMore, setHasMore] = useState(true); //是否还有更多数据需要加载
const PAGE_SIZE = 10; //每页数量
const [page, setPage] = useState(1); //当前页,默认第一页开始
//数据处理/下一页/是否继续请求
const getSelectArr = () => {
if (loading || !hasMore) {
return;
}
setLoading(true);
try {
const {success,data,errorMsg}=await getSelectArrApi() //api请求
const errorMsg = null;
if (success) {
setSelectArr((prevData) => [...prevData, ...data]); // 更新数据(eg:第二页和第一页合并数组,第三页和前两页合并...)
setPage(page + 1); //更新为下一个(eg:第一页变成请求第二页,再第三页..,以此类推...)
setHasMore(data.length === PAGE_SIZE); //对比,当返回的新数组长度小于pagesize,则说明,数据已经全部拿到; 反之说明,还有下一页
} else {
message.error(errorMsg);
}
setLoading(false);
} catch (err) {
console.error(err);
}
};
//滚动时操作函数
const handleScroll = (event) => {
//scrollTop:获取或设置一个元素的内容垂直滚动的像素数。
//scrollHeight:一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。
//clientHeight:元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。
const { scrollTop, scrollHeight, clientHeight } = event.target;
if (scrollHeight - (scrollTop + clientHeight) < 100) {
//滚动加载
getSelectArr();
}
};
useEffect(() => {
getSelectArr();
});
return (
<Select
showSearch
placeholder="选择查询的名称"
optionFilterProp="children"
onChange={(value: string) => console.log(`selected ${value}`)}
onSearch={(value: string) => console.log('search:', value)}
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={
Array.isArray(selectArr) &&
selectArr?.map((item) => {
return {
key: item.id,
label: item.name,
value: item.id,
};
})
}
virtual={true}
onPopupScroll={(e) => handleScroll(e)}
/>
);
};
export default App;
代码示例讲解