1.定义监听对象
useInViewport:观察元素是否在可见区域,以及元素可见比例
const ref = useRef<HTMLDivElement>(null);
const [inViewport] = useInViewport(ref);
const refScroll = useRef<HTMLDivElement>(null);
const [requestingTree, setRequestingTree] = useState(false); //请求状态
const [treeData, setTreeData] = useState({} as { data: guideTree[]; recordsTotal: number }); //数据
const [defaultParams] = useState({
length: 50,
searchMap: { status: '1' },
start: 0,
});
- 接口调用
// getTree 接口地址
const { runAsync: runGuideTree, loading: treeLoading } = useRequest(getTree, {
manual: true,
onSuccess: (result: any, params) => {
let newData = result?.data;
if (params[0].start !== 0) {
newData = treeData.data.concat(result.data);
}
setTreeData({ ...result, data: newData });
setRequestingTree(false);
},
defaultParams: [defaultParams],
});
- 根据inViewport 判断是否请求下一个数据
useUpdateEffect(() => {
if (!requestingTree && inViewport && (treeData!.data || []).length < +treeData.recordsTotal) {
setRequestingTree(true);
const obj = Object.assign(defaultParams, {
length: 50,
searchMap: {
status: '1'
},
start: treeData.data ? treeData.data.length + 1 : 0,
});
runGuideTree(obj);
}
}, [inViewport]);
- 页面渲染
<Spin spinning={treeLoading}>
<div className="tree">
{treeData && treeData.data && treeData.data.length === 0 ? (
<div className="tree-right-empty">
<FrownOutlined />
<div>暂无数据</div>
</div>
) : (
<Scrollbar ref={refScroll} style={{ zIndex: 999 }}>
{treeData &&
treeData.data &&
treeData.data.map((value, index) => (
<Itemdiv
ref={ref}
index={index}
className="tree-item border-need"
active={currentShop.id == value.id}
key={Math.random()}
onClick={async () => {
handlerCurrentSelect(value, {});
setCurrentShop(value);
}}
>
<TableOverflowText style={{ overflow: 'auto' }} content={value.label || ''} />
</Itemdiv>
))}
{(treeData!.data || []).length < +treeData.recordsTotal && inViewport && (
<div className="spins" style={{ zIndex: 1000 }}>
<Spin spinning={requestingTree} />
</div>
)}
{(treeData!.data || []).length + 1 === +treeData.recordsTotal && (
<div className="footers">已经到底部啦~</div>
)}
</Scrollbar>
)}
</div>
</Spin>