滚动加载 hooks

场景:触底加载下一页

代码思路: 触底的时候,page增加,监听page变化,触发请求,在page变化的时候把loading设置为 true,请求拿到数据之后loading设置为false

代码实现

import { useReducer, useLayoutEffect } from 'react'
import Taro from '@tarojs/taro'
import Services from '@/services'
import { useAsyncEffect } from '@/utils'

const UPDATE_STATE = 'UPDATE_STATE'
const DEFAULT_STATE = {
  page: 1,
  pageSize: 6,
  goodsList: [],
  total: 1,
  loading: false,
  isNoMore: false,
  swiperheight: 0,
}

const reducer = (state, action) => {
  switch (action.type) {
    case UPDATE_STATE:
      return {
        ...state,
        ...action.data,
      }
  }
}

export default (category) => {
  const [
    { page, pageSize, goodsList, loading, isNoMore, swiperheight },
    dispatch,
  ] = useReducer(reducer, DEFAULT_STATE)
//page变化触发getGoodsList() 请求
  useAsyncEffect(async () => {
      // dispatch({ type: UPDATE_STATE, data: { loading: true } })

      if(!category){
          resetScrollList()
      }else{
          getGoodsList()
      }
  }, [category, page])

//触底的时候触发的方法:此时page增加的同时loading打开
  const onPaginationChange = () => {
  //如果loading为真代表请求还没有开始发送或者未发送完,则不执行下一次请求
    if (loading) return
    //如果没有更多数据为真,就关闭loading,不发送下一次请求
    if (isNoMore) {
      dispatch({ type: UPDATE_STATE, data: { loading: false} })
      return
    }
    dispatch({ type: UPDATE_STATE, data: { page: page + 1 ,loading:true} })
  }
//数据清理为空,如果没有category参数 就是没有数据
  const resetScrollList = () => {
    dispatch({
      type: UPDATE_STATE,
      data: { page: 1, goodsList: [], isNoMore: false },
    })
  }
//发送请求
  const getGoodsList = async () => {
    if (!category) return
    //请求,根据实际需要取
    const { data } = await Services.goods.search({
      item_type: 'normal',
      is_point: false,
      distributor_id: '0',
      approve_status: 'onsale,only_show',
      category: category.category_id,
      main_category: category.main_category_id,
      page,
      pageSize,
    })
    if (data.list.length < pageSize) {
      dispatch({ type: UPDATE_STATE, data: { isNoMore: true } })
    }

    const newGoodsList = goodsList.concat(data.list)
    //另一种写法
    //```const newGoodsList = page === 1 ? data : [...goodsList,...data]
    dispatch({
      type: UPDATE_STATE,
      data: { goodsList: newGoodsList, loading: false },
    })
  }

  return {
    goodsList,
    page,
    onPaginationChange,
    resetScrollList,
    loading,
    isNoMore,
    swiperheight,
  }
}

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享