|
@@ -3,7 +3,7 @@ import Taro from '@tarojs/taro';
|
3
|
3
|
import { View } from '@tarojs/components';
|
4
|
4
|
import usePrevious from '@/utils/hooks/usePrevious';
|
5
|
5
|
import Column from './Column';
|
6
|
|
-import { useList } from './hooks';
|
|
6
|
+import { useColumn, useRenderFunc } from './hooks';
|
7
|
7
|
import { classNames, getRect } from './utils';
|
8
|
8
|
|
9
|
9
|
import './style.less'
|
|
@@ -17,7 +17,7 @@ import './style.less'
|
17
|
17
|
*/
|
18
|
18
|
|
19
|
19
|
export default (props) => {
|
20
|
|
- const { className, listData, itemKey, render } = props
|
|
20
|
+ const { className, listData, render } = props
|
21
|
21
|
|
22
|
22
|
// rfTimes 用来区分是否更换数据源
|
23
|
23
|
const { list, rfTimes: refresh } = listData
|
|
@@ -28,14 +28,15 @@ export default (props) => {
|
28
|
28
|
const lastList = usePrevious(list)
|
29
|
29
|
const lastRf = usePrevious(refresh)
|
30
|
30
|
|
|
31
|
+
|
31
|
32
|
// 记录左右2栏的数据及高度
|
32
|
33
|
const leftHeight = useRef(0)
|
33
|
34
|
const rightHeight = useRef(0)
|
34
|
|
- const [leftList, leftRef, setLeftList] = useList()
|
35
|
|
- const [rightList, rightRef, setRightList] = useList()
|
36
|
|
-
|
37
|
|
- // 用来强制更新组件
|
38
|
|
- const [cursor, setCursor] = useState(-1)
|
|
35
|
+ const [leftList, appendLeft, setLeftList] = useColumn()
|
|
36
|
+ const [rightList, appendRight, setRightList] = useColumn()
|
|
37
|
+
|
|
38
|
+ // 渲染逻辑
|
|
39
|
+ const forceRender = useRenderFunc(renderListRef, leftHeight, rightHeight, appendLeft, appendRight)
|
39
|
40
|
|
40
|
41
|
// 每个元素渲染完成, 会拿到当前栏的高度
|
41
|
42
|
const handleRenderFinish = (direct) => (height) => {
|
|
@@ -45,58 +46,35 @@ export default (props) => {
|
45
|
46
|
rightHeight.current = height
|
46
|
47
|
}
|
47
|
48
|
|
48
|
|
- // 触发强制渲染
|
49
|
|
- setCursor(cursor + 1)
|
|
49
|
+ //
|
|
50
|
+ forceRender.current()
|
50
|
51
|
}
|
51
|
|
-
|
|
52
|
+
|
|
53
|
+ console.debug('------leftHeight------->', leftHeight.current)
|
|
54
|
+ console.debug('------rightHeight------->', rightHeight.current)
|
|
55
|
+ console.debug('------renderListRef------->', renderListRef.current)
|
|
56
|
+ console.debug('------list------->', list)
|
|
57
|
+
|
52
|
58
|
useEffect(() => {
|
|
59
|
+ if (lastList && lastList === list) return;
|
|
60
|
+
|
53
|
61
|
// 新数据源 = 首次进入 或者 切换数据源
|
54
|
62
|
const isNew = (!lastList?.length && list.length) || (lastRf !== refresh)
|
55
|
|
-
|
|
63
|
+
|
56
|
64
|
if (!isNew) {
|
57
|
|
- // 非新数据源, list 变更那就说明是执行了上拉加载
|
58
|
|
- const addedList = []
|
59
|
|
- for (let item of list) {
|
60
|
|
- const found = lastList.filter(x => x[itemKey] === item[itemKey])[0]
|
61
|
|
- if (!found) {
|
62
|
|
- addedList.push(item)
|
63
|
|
- }
|
64
|
|
- }
|
65
|
|
-
|
|
65
|
+ // 非新数据源, list 变更那就说明是执行了上拉加载
|
66
|
66
|
// 于是, 只继续绘制变更的那部分
|
67
|
|
- renderListRef.current = addedList
|
68
|
|
- setCursor(-2)
|
|
67
|
+ renderListRef.current = list.slice(lastList.length)
|
69
|
68
|
} else {
|
70
|
|
- setCursor(0)
|
|
69
|
+ leftHeight.current = 0
|
|
70
|
+ rightHeight.current = 0
|
71
|
71
|
setLeftList([])
|
72
|
72
|
setRightList([])
|
73
|
73
|
renderListRef.current = list ? list.slice() : []
|
74
|
|
- leftHeight.current = 0
|
75
|
|
- rightHeight.current = 0
|
76
|
|
-
|
77
|
|
- if (renderListRef.current.length) {
|
78
|
|
- setCursor(0)
|
79
|
|
- } else {
|
80
|
|
- setCursor(-1)
|
81
|
|
- }
|
82
|
74
|
}
|
83
|
|
- }, [list])
|
84
|
|
-
|
85
|
|
- useEffect(() => {
|
86
|
|
- // 如果当前渲染数据为空
|
87
|
|
- if (!renderListRef.current.length) return;
|
88
|
|
-
|
89
|
|
- // 每次把数组最上面的一个拿出来
|
90
|
|
- const item = renderListRef.current.shift()
|
91
|
|
- item.__vid = `f-${Math.random().toString(36).substring(2)}`
|
92
|
75
|
|
93
|
|
- // 优先放入低高度的栏里面
|
94
|
|
- if (leftHeight.current <= rightHeight.current) {
|
95
|
|
- setLeftList([...leftRef.current, item])
|
96
|
|
- } else {
|
97
|
|
- setRightList([...rightRef.current, item])
|
98
|
|
- }
|
99
|
|
- }, [cursor])
|
|
76
|
+ forceRender.current()
|
|
77
|
+ }, [lastList, list])
|
100
|
78
|
|
101
|
79
|
return (
|
102
|
80
|
<View className={classNames(className, 'masonry-layout')}>
|