下拉加载更多的实现

2020-06-11  本文已影响0人  sweetBoy_9126

1.四个属性
Data // 存储列表数据
hasMore // 是否还有更多数据,对应接口是否还有下一页的字段
isLoadingMore // 记录当前状态,用来展示'加载中...' 或 '加载更多'
page // 页码

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>
  )
}
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;
上一篇下一篇

猜你喜欢

热点阅读