封装一个工具函数对list实现滚到加载
Published: 2023-03-07 07:23:25

##滚动加载需要实现的功能
- 当调用loadMore函数时，pageNum加1
- 调用query时，如果没有传入pageNum则默认重新加载，已查询到的数据清空，重新查询

####模拟后端接口
- 后端的接口数据格式
```java
public class ResultType {
    private Boolean Success;
    private Integer Code;
    private String Message;
    private PaginationResult paginationResult;
}
public class PaginationResult {
    private Integer total;
    private List<HashMap<String,? extends Object>> items;
    private Boolean next;
}
```
- 模拟后端返回数据
```java
@RestController
@RequestMapping("/inno")
@CrossOrigin
public class CommonController {
    Integer total=1;
    @GetMapping("list")
    public R findAll(){
        ArrayList<String> arrayList = new ArrayList<>();
       total= total+1;
        arrayList.add("inno:"+total);
        HashMap<String,Object> map = new HashMap<>();
        map.put("items",arrayList);
        map.put("total",total);
        map.put("next",true);
        if (Objects.equals(total,8)){
            map.put("next",false);
        }
        return R.ok().Data(map) ;
    }
}
```
####前端封装对应的axios请求
```typescript
import axios, { AxiosRequestConfig } from "axios";
import { ResultType } from "./requestType";

const baseURL = "http://localhost:8080/"
const instance = axios.create({
  baseURL: baseURL,
  timeout: 1000,

});
// Add a request interceptor
instance.interceptors.request.use(function (config) {
  // Do something before request is sent
 
  return config;
}, function (error) {
  // Do something with request error
  return Promise.reject(error);
});

// Add a response interceptor
instance.interceptors.response.use(function (response) {
  // Any status code that lie within the range of 2xx cause this function to trigger
  // Do something with response data
  return response ;
}, function (error) {
  // Any status codes that falls outside the range of 2xx cause this function to trigger
  // Do something with response error
  return Promise.reject(error);
});

const axiosGet =<T>({ url, params, headers={} }: AxiosRequestConfig):Promise<ResultType<T>> => {
  headers["Content-Type"] = 'application/json;charset=utf-8'
  return new Promise(async (resolve, reject) => {
    try {
      const result =await instance({
        url,
        method: "get",
        params: params,
        headers
      })
      const resultData=result.data as ResultType<T>
      resolve(resultData)

  
    } catch (error) {

      reject(error)
    }
  })
}

export {axiosGet}
```
####前端对应的数据类型
```typescript
export type ResultType<T>={
    code:number,
    success:boolean,
    message:string,
    data:T
}
export type PaginationType<T>={
    total:number,
    items:T[]
    next:boolean
}
```
####Asl滚动加载list组件
```typescript
import { useRequest } from 'ahooks'
import { message } from 'antd'
import { AxiosHeaders } from 'axios'
import { set } from 'immer/dist/internal'
import {useCallback, useEffect, useState} from 'react'
import { axiosGet } from '../../api'
import { PaginationType } from '../../api/requestType'
type Props={
  url:string  
}
type queryParamType={
    pageSize:number
    pageNum:number
    [key:string]:any
}
const useAml=<T>(url:string)=>{
    const [lists, setLists] = useState<T[]>([])
    const [queryParam, setQueryParam] = useState<queryParamType>({pageSize:10,pageNum:1})
    const [next, setNext] = useState<boolean>(true)
    const [total, setTotal] = useState<number>(0)
    const fetchData=useCallback(async ()=>{    
        try {
         const result=  await axiosGet<PaginationType<T>>({url,params:queryParam})
         return result
        } catch (error) {
           throw  error
        } 
    },[]) 
    const {loading  } = useRequest(fetchData,{
        manual: false,
        onSuccess: (result, params) => {
            const {total,items,next}=result.data
            setLists(lists=>([...lists,...items]))
            setTotal(total)
            setNext(next)
          },
          onError: (error) => {
            message.error(error.message);
          },
          refreshDeps: [url,queryParam],
          debounceWait: 1000,
    })
    const initialList=()=>{
       setLists([]);
       setNext(true);
       setTotal(0); 
    }
    const query=(params:{
        pageSize?:number
        pageNum?:number
        [key:string]:any
    })=>{
        if (!params.pageNum) {
        initialList() 
        }
        setQueryParam(queryParam=>({...queryParam,...{pageSize:10,pageNum:1},...params}))
    }

    const loadMore=()=>{
        if (next) {
            setQueryParam(queryParam=>({...queryParam,pageNum:queryParam.pageNum+1})) 
        }
    }
    const resetQuery=()=>{
        setQueryParam({pageSize:10,pageNum:1})
    }
    return {lists,next,total,loading,query,loadMore}
}
export default useAml
```
####实现效果

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsem8gsqadrffg7hh6yk.png)