index.jsx 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
  2. import { ScrollView } from '@tarojs/components';
  3. import Taro from '@tarojs/taro';
  4. export default (props) => {
  5. const {
  6. render,
  7. request,
  8. params,
  9. pageSize = 10,
  10. onError,
  11. onDataChange,
  12. ...leftProps
  13. } = props
  14. const loadingRef = useRef(false)
  15. const [payload, setPayload] = useState({})
  16. const [list, setList] = useState([])
  17. const pageRef = useRef({ current: 1, pages: 0 })
  18. const hasMore = pageRef.current.current < pageRef.current.pages
  19. // 滚动
  20. const handleScrollToLower = (e) => {
  21. const loading = loadingRef.current
  22. if (!loading && hasMore) {
  23. setPayload({
  24. ...payload,
  25. pageNum: pageRef.current.current + 1
  26. })
  27. }
  28. }
  29. const fetchList = (queryParams) => {
  30. if (!request) return;
  31. Taro.showLoading()
  32. loadingRef.current = true
  33. request(queryParams).then((res) => {
  34. const { records, ...pageInfo } = res || {}
  35. const lst = pageInfo.current === 1 ? records || [] : list.concat(records || [])
  36. setList(lst)
  37. if (onDataChange) {
  38. onDataChange(lst)
  39. }
  40. pageRef.current = pageInfo
  41. loadingRef.current = false
  42. Taro.hideLoading()
  43. }).catch((err) => {
  44. loadingRef.current = false
  45. console.error(err)
  46. Taro.hideLoading()
  47. if (onError) {
  48. onError(err)
  49. }
  50. })
  51. }
  52. const fetchRef = useRef()
  53. fetchRef.current = fetchList
  54. // 联动状态, 设置查询参数
  55. useEffect(() => {
  56. setPayload({
  57. ...params || {},
  58. pageNum: 1,
  59. pageSize,
  60. })
  61. }, [pageSize, params])
  62. // 请求数据
  63. useEffect(() => {
  64. fetchRef.current(payload)
  65. }, [payload])
  66. return (
  67. <ScrollView
  68. scrollY
  69. onScrollToLower={handleScrollToLower}
  70. {...leftProps}
  71. >
  72. {!render
  73. ? props.children
  74. : list.map((item, index) => render({ item, index }))
  75. }
  76. <view className='botton' style={{ display: hasMore ? 'none' : '' }}>已经到底了~</view>
  77. </ScrollView>
  78. )
  79. }