- 如何判断何时加载 根据antd List中的loadMore属性 当loadMore按钮在可视区域时,加载数据,反之不加载数据
- 如何判断loadMore按钮是否在可见区域内 使用ahooks的useInViewport判断
- 无限滚动加载数据(只有滚动加载时才需要请求数据放在同一个数组中) 增加滚动加载的标识
const newItems = asl.infinite ? asl.items.concat(items) : items
1.编辑参数(page:1,pageSize:10,infinite:false)
2.删除参数(page:1,pageSize:10,infinite:false)
3.查询参数(page:1,pageSize:10,infinite:false)
4.无限滚动加载参数(page:page+1,pageSize:10,infinite:true)
只需在每次调用加载数据时page加一即可
so now i will show you how to achieve it
- package AutoLoadMoreList component we need some basic conditions to judge
import { useDebounceEffect, useInViewport } from "ahooks";
import { Button, List, Spin } from "antd"
import { useRef } from "react";
interface Props<T> {
height?: number
dataSource: T[]
renderItem: (item: T) => React.ReactNode
loading:boolean //是否正在请求数据true:正在请求,false:请求完成
loadMore:()=>void //滚动加载数据
next:string|null //是否还有数据
}
function AutoLoadMoreList<T>({ height, dataSource, renderItem,loading,loadMore,next }: Props<T>) {
const loadMoreButtonRef = useRef(null)
const [inViewport] = useInViewport(loadMoreButtonRef)
useDebounceEffect(()=>{
if (inViewport) { //如果在可视区域加载数据
if (next) {
loadMore()
}
}
},[inViewport],{ wait: 1000})
const loadMoreButton = <div
ref={loadMoreButtonRef}
style={{
textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
}}
>
<Button>loading more</Button>
</div>
return <div style={{ height: height }}>
<Spin spinning={loading}>
<List
className="demo-loadmore-list"
itemLayout="horizontal"
loadMore={loadMoreButton}
dataSource={dataSource}
renderItem={renderItem}
/>
</Spin>
</div>
}
export default AutoLoadMoreList
- package request conponent
import request from '@/packages/request';
import { useDebounceEffect } from 'ahooks';
import { message } from 'antd';
import { useState} from 'react'
interface responseType<T>{
ok:boolean
count:number|null
next:string|null
results:T|null
error:string
}
interface GetType{url:string
params:Record<string,unknown>}
const Get=async<T>({url,params}:GetType):Promise<responseType<T>>=>{
try {
const result= await request(url, { method: 'GET', params: params }) as any
return {
ok:true,
count:result.data.count as number,
next:result.data.next,
results:result.data.results as T,
error:''
}
} catch (error) {
return {
ok:false,
count:null,
next:null,
results:null,
error: 'fail'
}
}
}
type QueryType={
page:number
pageSize:number
[key:string]:unknown
}
function useAsl<T>(url:string) {
const [infinite,setInfinite] =useState<boolean>(false)
const [query,setQuery]= useState<QueryType>({page:1,pageSize:10})
const [loading,setLoading]= useState<boolean>(false)
const [dataSource, setDataSource] = useState<T[]>([])
const [next, setNext] = useState<string|null>(null)
useDebounceEffect(()=>{
const getList=async()=>{
setLoading(true)
const {ok,results,error,next}=await Get<T[]>({url,params:query})
if (ok&&results) {
const dateArr= infinite ?dataSource.concat(results):results
setDataSource(dateArr)
setNext(next)
}else{
message.error(error)
}
setLoading(false)
}
getList().then()
},[url,query],{wait:100})
const loadMore=()=>{
setInfinite(true)
setQuery(query=>({...query,page:query.page+1}))
}
return {dataSource,loading,loadMore,next}
}
export default useAsl
- use it
const {dataSource,loading,loadMore,next}= useAsl<NotificationType>('/notice_message/message/manage')
<div className={Styles.tabTwo}>
<AutoLoadMoreList<NotificationType>
dataSource={dataSource}
loading={loading}
loadMore={loadMore}
next={next}
renderItem={(item)=><div key={item.uuid}>{item.content}</div>}
/>
</div>
- achievement
Top comments (0)