1.四个属性
Data // 存储列表数据
hasMore // 是否还有更多数据,对应接口是否还有下一页的字段
isLoadingMore // 记录当前状态,用来展示'加载中...' 或 '加载更多'
page // 页码
- List.tsx
const List: React.FC = () => {
const {state} = useContext<ContextProp>(Context)
const [Data, setData] = useState<ObjProp[]>([])
// 是否还有更多数据
const [hasMore, setHasMore] = useState<boolean>(false)
// 记录当前状态,是加载中...,还是点击加载更多
const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false)
// 下一页的页码,首页的页码是0
const [page, setPage] = useState<number>(0)
const resultHandle = (result: Promise<Response>) => {
result.then(res => {
return res.json()
}).then(json => {
const { data, hasMore } = json
setData(Data.concat(data))
setHasMore(hasMore)
})
}
const getPageData = () => {
const cityName = state.cityName
const result = getListData(cityName, page)
resultHandle(result)
}
const loadMoreData = () => {
setIsLoadingMore(true)
setPage(page => page + 1)
setIsLoadingMore(false)
}
useEffect(() => {
getPageData()
}, [])
useEffect(() => {
if (isLoadingMore) {
getPageData()
}
}, [page])
return (
<div>
{Data.length > 0 ? <ListComponent data={Data}/> : '加载中...'}
// 如果还有下一页或者更多数据的情况下才显示加载更多
{hasMore ? <LoadMore isLoadingMore={isLoadingMore} loadMoreFn={loadMoreData}/> : <div></div>}
</div>
)
}
- LoadMore.tsx
interface Prop {
isLoadingMore: boolean;
loadMoreFn: () => void;
}
const LoadMore: React.FC<Prop> = (props) => {
let timer: number | null = null
const loadRef = useRef<HTMLDivElement>(null)
const scrollBottomGetData = () => {
// 当前加载更多文字距可视窗口顶部的位置
const top = loadRef.current!.getBoundingClientRect().top
// 窗口的高度
const windowH = window.screen.height
// 如果小于窗口的高度,说明进入可视范围内了,也就是到底了
if (top && top < windowH) {
props.loadMoreFn()
}
}
const onScroll = () => {
if (props.isLoadingMore) {
return
}
if (timer) {
window.clearTimeout(timer)
}
timer = window.setTimeout(scrollBottomGetData, 500)
}
useEffect(() => {
document.addEventListener('scroll', onScroll)
return () => {
document.removeEventListener('scroll', onScroll)
}
}, [])
return (
<div className={"load-more"} ref={loadRef}>
{
props.isLoadingMore ? <span>加载中...</span>
: <span>加载更多</span>
}
</div>
)
}
export default LoadMore;
网友评论