You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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;

关键说明

  1. 绑定正确的滚动容器:通过useRef获取<FileList>的DOM节点,这才是Chonky中真正承载文件列表的滚动容器。
  2. useInfiniteQuery核心配置:
    • queryKey:唯一标识文件查询,确保React Query的缓存和更新逻辑正常工作。
    • queryFn:接收分页参数pageParam,发起对应页码的文件请求。
    • getNextPageParam:根据最后一页的返回数据判断是否还有下一页,返回下一页的页码或undefined来终止加载。
  3. 滚动触发逻辑:计算滚动位置,当满足「接近底部、存在下一页、当前未在加载」三个条件时,触发下一页加载。

注意事项

  • 如果<FileList>的ref无法直接获取DOM元素(比如组件内部做了多层封装),可以查看Chonky渲染后的DOM结构,找到带有overflow: auto/scroll的容器元素,用document.querySelector结合类名获取(比如Chonky的文件列表容器类名通常是chonky-file-list)。
  • 可以根据需求调整滚动触发加载的阈值(比如把20px改成50px),让加载触发更提前,提升用户体验。
  • 可以在页面底部添加加载状态提示,比如当isFetchingNextPage为true时显示「加载中...」。

内容的提问来源于stack exchange,提问作者Mike Alibo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:20:18