张延森 3 年前
父节点
当前提交
2443c12a7e
共有 1 个文件被更改,包括 83 次插入0 次删除
  1. 83
    0
      src/components/List/index.jsx

+ 83
- 0
src/components/List/index.jsx 查看文件

@@ -0,0 +1,83 @@
1
+import React, { useEffect, useMemo, useRef, useState } from 'react';
2
+import VirtualList from '@tarojs/components/virtual-list';
3
+import Taro from '@tarojs/taro';
4
+
5
+export default (props) => {
6
+  const {
7
+    className,
8
+    height,
9
+    width = '100%',
10
+    itemHeight = 100,
11
+    render,
12
+    request,
13
+    params,
14
+    pageSize = 10,
15
+    onError
16
+  } = props
17
+
18
+  const loadingRef = useRef(false)
19
+  const [payload, setPayload] = useState({})
20
+  const [list, setList] = useState([])
21
+  const pageRef = useRef({ current: 1, total: 0 })
22
+
23
+  const dataLen = list.length
24
+
25
+  // 滚动
26
+  const handleScroll = ({ scrollDirection, scrollOffset }) => {
27
+    const loading = loadingRef.current
28
+    const isUping = scrollDirection === 'forward'
29
+    const canScroll = scrollOffset > ((dataLen - 5) * itemHeight + 100)
30
+    const hasMore = pageRef.current.current < pageRef.current.total
31
+
32
+    if (!loading && isUping && canScroll && hasMore) {
33
+      setPayload({
34
+        ...payload,
35
+        pageNum: pageRef.current.current + 1
36
+      })
37
+    }
38
+  }
39
+
40
+  // 联动状态, 设置查询参数
41
+  useEffect(() => {
42
+    setPayload({
43
+      ...params,
44
+      pageNum: pageRef.current,
45
+      pageSize,
46
+    })
47
+  }, [pageSize, params])
48
+
49
+
50
+  // 请求数据
51
+  useEffect(() => {
52
+    Taro.showLoading()
53
+    loadingRef.current = true
54
+    request(payload).then((res) => {
55
+      const { records, ...pageInfo } = res || {}
56
+      setList(records || [])
57
+      pageRef.current = pageInfo
58
+      loadingRef.current = false
59
+      Taro.hideLoading()
60
+    }).catch((err) => {
61
+      loadingRef.current = false
62
+      console.error(err)
63
+      Taro.hideLoading()
64
+      if (onError) {
65
+        onError(err)
66
+      }
67
+    })
68
+  }, [payload])
69
+
70
+  const Row = useMemo(render, [])
71
+
72
+  return (
73
+    <VirtualList
74
+      className={className}
75
+      width={width}  
76
+      height={height}
77
+      itemData={list}
78
+      itemCount={dataLen}
79
+      itemSize={itemHeight}
80
+      onScroll={handleScroll}
81
+    >{Row}</VirtualList>
82
+  )
83
+}