AHooks无限滚动useInfiniteScroll使用

useInfiniteScroll基本介绍

useInfiniteScroll 封装了常见的无限滚动逻辑。

const { data, loading, loadingMore, loadMore } = useInfiniteScroll(service);

useInfiniteScroll 的第一个参数 service 是一个异步函数,对这个函数的入参和出参有如下约定:

  • service 返回的数据必须包含 list 数组,类型为 { list: any[], …rest }
  • service 的入参为整合后的最新 data

假如第一次请求返回数据为 { list: [1, 2, 3] }, 第二次返回的数据为 { list: [4, 5, 6] }, 则我们会自动合并 list,整合后的的 data 为 { list: [1, 2, 3, 4, 5, 6] }。

注:这里官方说了对于返回的字段是list,才会帮你进行合并,所以可以跟后端的同学商量返回的数组数据用list做属性名,或者你也可以拿到后端的数据自己生成list属性名。

其他参数及API请访问官网:https://ahooks.js.org/zh-CN/hooks/use-infinite-scroll

实际使用

import './styles.less';
import { useEffect, useRef, useState } from 'react';
import { useInfiniteScroll } from 'ahooks';
import { Spin } from 'antd';

const GlobalHeader = (props: any) => {

  const noticeScrollParentRef = useRef(null) as any;
  

  // 数据请求
  const loadNoticeList = async (current = 1) => {
    const result = await apiGetNoticeList({
      pageSize: 10,
      current,
    });
    // 必须包含 list 这个字段,最好 total、page 也带上 { list: any[], ... }
    const dataList = {
      list: result?.data?.records || [],
      total: result?.data?.total || 0,
      page: current,
    };
    return dataList;
  };


  // 滚动加载
  const {
    data: noticeData,
    loading: noticeLoading,
    loadingMore: noticeLoadingMore,
    noMore: noticeNoMore,
    reload: noticeReload,
  } = useInfiniteScroll(
    (d) => {
      const page = d ? Math.ceil(d?.list?.length / PAGE_SIZE) + 1 : 1;
      return loadNoticeList(page);
    },
    {
      target: noticeScrollParentRef,
      isNoMore: (d: any) => d?.total <= d?.list?.length,
      threshold: 10,
      // 以下onBefore和onFinally,如出现滚动条跳顶情况才需要
      onBefore: () => {
        // 优化加载更多时,滚动条会自动跳顶的问题
        setTimeout(() => {
          const parentRef = noticeScrollParentRef.current;
          if (parentRef && parentRef.childElementCount > 10) {
            const itemHeight = parentRef.firstChild?.offsetHeight || 80;
            parentRef.scrollTo({
              top: parentRef.lastChild?.offsetTop - itemHeight,
              behavior: 'instant',
            });
          }
        });
      },
      onFinally: (data) => onFinally(data, noticeScrollParentRef),
    },
  );
  
  // 优化加载更多时,滚动条会自动跳顶的问题
  const onFinally = (data: any, ref: any) => {
    if (data?.page === 1) return;
    const parentRef = ref.current;
    if (!parentRef) return;
    const itemHeight = parentRef.firstChild?.offsetHeight || 80;
    parentRef.scrollTo({
      top:
        parentRef.lastChild?.offsetTop - (data?.list?.length + 1) * itemHeight,
      behavior: 'instant',
    });
  };
  
  
  return (
    <div ref={noticeScrollParentRef} className="scroll-wrapper">
      {noticeData && noticeData?.list && noticeData?.list.length > 0
        ? noticeData?.list.map((item: any) => (
            <div key={item.id}>xxx</div>
          ))
        : null}
      {noticeLoading || noticeLoadingMore ? (
        <Spin spinning>
          <p className="footer-loading"></p>
        </Spin>
      ) : null}
    </div>
  )
};

样式(外层必须有高度和开启滚动):

// styles.less
.scroll-wrapper {
  width: 100%;
  height: 200px;
  overflow: auto;
}



码字不易,觉得有帮助的小伙伴点个赞支持下~


关注我的订阅号AIQ999~

### ahooks 与 Wagmi 的对比 #### 功能定位 ahooks 是一个基于 React Hooks 的增强库,提供了许多实用的自定义 Hook 来简化常见的开发场景。这些 Hook 可以帮助开发者更高效地处理诸如数据获取、表单管理等任务[^1]。 Wagmi 则专注于 Web3 领域的应用程序开发,特别是与 Ethereum 区块链交互的功能。它提供了一系列专门设计用于连接钱包、读取区块链状态以及发送交易等功能的 Hooks[^2]。 #### 使用场景 对于构建传统Web应用而言,ahooks 提供了丰富的工具集来提升生产力并保持良好的可维护性;而对于涉及去中心化金融 (DeFi) 或者其他基于区块链技术的产品来说,则更适合采用像 wagmi 这样的专用解决方案来进行快速迭代和发展[^3]。 ```javascript // Example using ahooks for form management import { useForm } from 'ahooks'; const MyFormComponent = () => { const [form] = useForm(); return ( <form> {/* Form elements */} </form> ); }; ``` ```typescript // Example using wagmi to interact with Ethereum blockchain import { useAccount, useConnect, useDisconnect } from 'wagmi'; import { MetaMaskConnector } from 'wagmi/connectors/metaMask'; function App() { const { isConnected } = useAccount(); const { connect } = useConnect({ connector: new MetaMaskConnector(), }); const { disconnect } = useDisconnect(); return ( <> {!isConnected ? ( <button onClick={() => connect()}>Connect</button> ) : ( <button onClick={() => disconnect()}>Disconnect</button> )} </> ); } ``` #### 差异总结 - **领域专注度**: ahooks 更加通用,适用于广泛的前端应用场景;而 wagmi 主要针对区块链行业内的需求进行了优化。 - **社区支持和技术文档**: 两个项目都有活跃的开源社区,在 GitHub 上可以找到详细的 API 文档和支持资源。 - **性能表现**: 由于各自侧重点不同,因此在特定的任务上可能会有不同的效率优势——比如 ahooks 在常规业务逻辑上的灵活性较高,wagmi 对于加密货币操作的支持更为深入[^4].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张兴华(MarsXH.Chang)

喜欢的可以请作者喝杯咖啡~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值