寻找最常自定义hooks-----分页篇

2,692 阅读2分钟

寻找最常自定义hooks-----分页篇

什么是分页

所有项目中请求种类最多的情况之一,主要应用于大量数据无法同时渲染或展示,借助Table组件去进行渲染,或者下拉后触底触发新请求,追加额外的数据。

那么,如何封装一个快捷,简单,有效的hooks,使代码更加简洁,操作简单就是我们的目标了。

上代码

code.png

代码介绍

这是我自己封装的hooks,对外提供了list,total,params,getList,hasMore几个属性,下面一一介绍

total:总数,用于存储接口返回的总数数据

loading:请求中状态,接口未完成,则为true,接口响应完成则为false

params:参数,当前查询使用的参数数据

hasMore:是否还有更多的数据,属于total数据的延申,判断当前页后面是否还会有数据,基本上应用于追加渲染的时候的判断

getList (param,option)=>void :调用请求,param会和上面的params参数进行合并,option用于设置数据是追加还是覆盖

list:就是你自己返回的数组数据。

优点

在业务场景需要多个参数,且参数不在同一组件内部时,特别好用。借助状态管理,实现简单的数据传递和调用。

例子

store.png 两个组件内部可以设置两种属性,且属性共存,简直太棒了。

进阶一下,如果各个组件内渲染也使用params,那么还可以做到在B组件里求改A组件的数据(就可以实现联动了)。

哪怕你是只用在单一组件内部,也可以节约大量的空间,讲业务和渲染拆分。

缺点

理解比较难一些吧,新手多看看,是提升自己的重要一步哦

hooks代码

import { useState, useEffect, useCallback } from "react";
import { getXXXList } from "@/service/XXXService";

// 自定义翻页请求hooks
function useList({ api, initialParams }) {
  // 接口参数
  const [params, setParams] = useState(initialParams);
  // 数据
  const [list, setList] = useState([]);
  // 是否还在请求中
  const [loading, setLoading] = useState(false);
  // 是否还有更多数据
  const [hasMore, setHasMore] = useState(true);
  // 总数
  const [total, setTotal] = useState(0);
  // 是叠加还是翻页
  const [add, setAdd] = useState(false);
  // hooks自身第一次useEffect不执行,需要外部调用getList触发useEffect
  const [key, setKey] = useState(false);

  // 采用参数合并的方式
  const getList = useCallback(
    (param, option = {}) => {
      const { isAdd = false } = option;
      setParams({ ...params, ...param });
      setAdd(isAdd);
      setKey(true);
    },
    [params]
  );

  useEffect(() => {
    if (!key) {
      return;
    }
    setLoading(true);
    api(params).then((res) => {
      setLoading(false);
      if (!res) {
        return;
      }
      const { pageSize, pageNo, items } = res;
      setHasMore(pageSize * pageNo < res.total);
      setTotal(res.total);
      setList(!add ? items : [...list, ...items]);
    });
  }, [params, add, key]);
  return { getList, list, loading, hasMore, total, params };
}

// 测试组件
function Test() {
  const { list, getList } = useList({
    api: getXXXList,
    initialParams: {
      pageSize: 10,
      pageNo: 1,
    },
  });

  const onClick = useCallback(() => {
    const pageSize = Math.floor(Math.random() * 10);
    getList({
      pageSize,
    });
  }, [getList]);

  useEffect(() => {
    getList();
  }, []);
  return (
    <div>
      <Button onClick={onClick}>点击发出请求</Button>
      {list.map((listItem) => (
        <ListItem item={listItem}></ListItem>
      ))}
    </div>
  );
}

function ListItem({ item }) {
  return <div></div>;
}

总结

可以根据自己项目实际情况修改当前hooks,也可以直接用。

每天进步亿点点,升职加薪迎娶白富美不是梦!!!祝愿我美梦成真。。。