值得一看
广告
彩虹云商城
广告

热门广告位

如何实现一个支持长列表无限加载的抽象Hook?

答案:useInfiniteList 封装了分页、加载状态和数据拼接,提供 loadMore 和 reset 方法,调用方只需传入请求函数。

如何实现一个支持长列表无限加载的抽象hook?

实现一个支持长列表无限加载的抽象 Hook,核心是把分页逻辑、加载状态和数据拼接封装起来,让调用方只需关注请求函数和参数。下面是一个基于 React 的 useInfiniteList Hook 实现。

1. 基本设计思路

这个 Hook 需要解决几个关键问题:

  • 管理当前页码或游标
  • 控制是否还能继续加载(是否有更多数据)
  • 处理加载中和错误状态
  • 自动合并新旧数据
  • 支持手动触发加载下一页

2. useInfiniteList 实现代码


function useInfiniteList(fetchFn, options = {}) {
  const { pageSize = 10, initialData = [] } = options;
  const [data, setData] = useState(initialData);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [error, setError] = useState(null);

  const loadMore = useCallback(async () => {
    if (loading || !hasMore) return;

    setLoading(true);
    setError(null);

    try {
      const result = await fetchFn({ page, pageSize });
      const { list, total } = result;

      // 判断是否还有更多数据
      const isLastPage = page * pageSize >= total;
      setHasMore(!isLastPage);

      // 合并数据
      setData(prev => […prev, …list]);
      setPage(prev => prev + 1);
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  }, [fetchFn, page, pageSize, loading, hasMore]);

  // 重置状态,用于刷新或更换查询条件
  const reset = useCallback(() => {
    setData([]);
    setPage(1);
    setHasMore(true);
    setError(null);
  }, []);

  return { data, loading, hasMore, error, loadMore, reset };
}

3. 使用示例

假设有一个获取文章列表的 API:

如知AI笔记

如知AI笔记

如知笔记——支持markdown的在线笔记,支持ai智能写作、AI搜索,支持DeepseekR1满血大模型

如知AI笔记27

查看详情
如知AI笔记


const fetchArticles = async ({ page, pageSize }) => {
  const res = await fetch(`/api/articles?page=${page}&limit=${pageSize}`);
  const json = await res.json();
  return {
    list: json.data,
    total: json.total
  };
};

// 组件中使用
function ArticleList() {
  const { data, loading, hasMore, loadMore } = useInfiniteList(fetchArticles);

  useEffect(() => {
    loadMore(); // 首次加载
  }, []);

  return (
    <div>
      {data.map(item => <div key={item.id}>{item.title}</div>)}
      {loading && <div>加载中…</div>}
      {!hasMore && !loading & & 没有更多内容}
      <button onClick={loadMore} disabled={!hasMore || loading}>
        加载更多
      </button>
    </div>
  );
}

4. 可扩展优化点

可以根据实际需求增强功能:

  • 支持滚动自动加载(监听 scroll 事件)
  • 加入防抖或节流防止频繁触发
  • 支持游标模式(cursor-based pagination)替代页码
  • 缓存已加载数据避免重复请求
  • 支持 SSR 或 Suspense 模式

基本上就这些。这个 Hook 抽象了通用逻辑,业务组件只需要传入请求方法即可复用。

相关标签:

react js json ai json NULL if 封装 try catch Error const finally map function 事件
温馨提示: 本文最后更新于2025-09-30 22:39:03,某些文章具有时效性,若有错误或已失效,请在下方留言或联系在线客服
文章版权声明 1 本网站名称: 创客网
2 本站永久网址:https://new.ie310.com
1 本文采用非商业性使用-相同方式共享 4.0 国际许可协议[CC BY-NC-SA]进行授权
2 本站所有内容仅供参考,分享出来是为了可以给大家提供新的思路。
3 互联网转载资源会有一些其他联系方式,请大家不要盲目相信,被骗本站概不负责!
4 本网站只做项目揭秘,无法一对一教学指导,每篇文章内都含项目全套的教程讲解,请仔细阅读。
5 本站分享的所有平台仅供展示,本站不对平台真实性负责,站长建议大家自己根据项目关键词自己选择平台。
6 因为文章发布时间和您阅读文章时间存在时间差,所以有些项目红利期可能已经过了,能不能赚钱需要自己判断。
7 本网站仅做资源分享,不做任何收益保障,创业公司上收费几百上千的项目我免费分享出来的,希望大家可以认真学习。
8 本站所有资料均来自互联网公开分享,并不代表本站立场,如不慎侵犯到您的版权利益,请联系79283999@qq.com删除。

本站资料仅供学习交流使用请勿商业运营,严禁从事违法,侵权等任何非法活动,否则后果自负!
THE END
喜欢就支持一下吧
点赞13赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容