如何基于react-query的useInfiniteQuery在Chonky IO中实现滚动加载?
在Chonky IO中实现滚动加载下一页(结合React Query useInfiniteQuery)
直接给<FullFileBrowser>添加onScroll事件无效的原因很明确:Chonky的FullFileBrowser组件本身并没有暴露onScroll这个props,实际的滚动行为发生在内部的<FileList>组件对应的DOM容器里,你的事件监听根本没绑定到正确的元素上。
解决方案代码示例
import { useInfiniteQuery } from '@tanstack/react-query'; import { FullFileBrowser, FileList, ChonkyIconFA } from 'chonky'; import { useEffect, useRef } from 'react'; const FileBrowser = () => { // 获取FileList的DOM节点引用 const fileListRef = useRef(null); // 用useInfiniteQuery实现分页加载逻辑 const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({ queryKey: ['files'], // 发起分页请求,pageParam默认从0开始,每页取50条 queryFn: async ({ pageParam = 0 }) => { const res = await fetch(`/api/files?page=${pageParam}&limit=50`); return res.json(); }, // 判断是否还有下一页:如果最后一页返回的文件为空,就没有下一页了 getNextPageParam: (lastPage, allPages) => { if (lastPage.files.length === 0) return undefined; return allPages.length; }, }); // 滚动到底部触发加载的逻辑 const handleScroll = () => { const scrollContainer = fileListRef.current; if (!scrollContainer) return; // 计算是否滚动到接近底部(留20px提前量,避免用户需要滚到最底部才触发) const isNearBottom = scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 20; if (isNearBottom && hasNextPage && !isFetchingNextPage) { fetchNextPage(); } }; // 给滚动容器绑定/解绑滚动事件 useEffect(() => { const container = fileListRef.current; if (container) { container.addEventListener('scroll', handleScroll); return () => container.removeEventListener('scroll', handleScroll); } }, [hasNextPage, isFetchingNextPage]); // 合并所有分页返回的文件数据 const files = data?.pages.flatMap(page => page.files) || []; return ( <FullFileBrowser files={files} iconComponent={ChonkyIconFA} > {/* 给FileList绑定ref,获取滚动容器 */} <FileList ref={fileListRef} /> </FullFileBrowser> ); }; export default FileBrowser;
关键说明
- 绑定正确的滚动容器:通过
useRef获取<FileList>的DOM节点,这才是Chonky中真正承载文件列表的滚动容器。 - useInfiniteQuery核心配置:
queryKey:唯一标识文件查询,确保React Query的缓存和更新逻辑正常工作。queryFn:接收分页参数pageParam,发起对应页码的文件请求。getNextPageParam:根据最后一页的返回数据判断是否还有下一页,返回下一页的页码或undefined来终止加载。
- 滚动触发逻辑:计算滚动位置,当满足「接近底部、存在下一页、当前未在加载」三个条件时,触发下一页加载。
注意事项
- 如果
<FileList>的ref无法直接获取DOM元素(比如组件内部做了多层封装),可以查看Chonky渲染后的DOM结构,找到带有overflow: auto/scroll的容器元素,用document.querySelector结合类名获取(比如Chonky的文件列表容器类名通常是chonky-file-list)。 - 可以根据需求调整滚动触发加载的阈值(比如把20px改成50px),让加载触发更提前,提升用户体验。
- 可以在页面底部添加加载状态提示,比如当
isFetchingNextPage为true时显示「加载中...」。
内容的提问来源于stack exchange,提问作者Mike Alibo
相关产品推荐
相关产品推荐

