Skip to content

作者

novlan1

2025.11.30

PixUI 中实现加载更多

1. 介绍

Press Pix 中已沉淀 useLoadMore hook,可以在不使用 VirtualList 组件时实现加载更多,适用于轻量、无需虚拟列表的场景。

2. 使用方式

组件内引入该 hook

tsx
import { useLoadMore } from 'press-pix/common/hooks/use-load-more';

// 组件
const OneComponent = ({
  // ... 已省略其他参数
  finished,
  onLoadMore,
}: {
  finished: boolean;
  onLoadMore: () => void;
}) => {
  useLoadMore(
    onLoadMore,
    {
      containerRef: listContainerRef,
      threshold: 100,
      debounceDelay: 100,
      isEnabled: true,
      finished,
    },
  );

  return (
    <div>
      {/* 列表容器 */}
      <div ref={listContainerRef}></div>
    </div>
  )
}

页面下完成加载更多逻辑。

tsx
const OnePage = () => {
  const [finished, setFinished] = useState(false);
  const loadingDataRef = useRef(false);
  
  const onLoadMore = () => {
    if (loadingDataRef.current) return;
    loadingDataRef.current = true;

    // 实际请求数据
    onGetList({
      isRefresh: false,
    });
  }

  const onGetList = (options?: {
    isRefresh?: boolean;
  }) => {
    // ... 用真实接口、真实参数代替
    getList({
      isRefresh: options?.isRefresh,
    })
      .then(() => {
        // 用业务真实逻辑代替
        setFinished(res.isFinished);
      }).finally(() => {
        loadingDataRef.current = false;
      })
  }

  return (
    <OneComponent
      finished={finished}
      onLoadMore={onLoadMore}
    >
  )
}

3. 参数说明

ts
const useLoadMore: (onReachBottom: any, options?: {
  threshold?: number;       // 滚动条与底部距离小于 threshold 时触发 onReachBottom 事件
  debounceDelay?: number;   // 防抖间隔
  isEnabled?: boolean;      // 是否开启
  finished?: boolean;       // 是否已加载完成
  containerRef?: any;       // 容器 ref
}) => {
  containerRef: any;
}

4. FAQ

4.1. 为什么要用 useRef 来存储 loadingDataRef

loading 状态使用 useRef,这样组件即使不用 debounce,也不会重复加载。

4.2. 为什么父组件自己维护 loading

父组件自己维护 loading,可以避免传来传去。

父组件一定是要用的,加载完回来后,会更新 loading,所以直接在父组件维护就行了,hook 里面不用再关心这个 loading 了。