|
@@ -1,6 +1,7 @@
|
1
|
1
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
2
|
2
|
import Taro from '@tarojs/taro';
|
3
|
3
|
import { View } from '@tarojs/components';
|
|
4
|
+import Item from './Item';
|
4
|
5
|
import { useList } from './hooks';
|
5
|
6
|
import { classNames, getRect } from './utils';
|
6
|
7
|
|
|
@@ -15,88 +16,58 @@ export default (props) => {
|
15
|
16
|
const rightBottom = useRef(0)
|
16
|
17
|
const [leftList, leftRef, setLeftList] = useList()
|
17
|
18
|
const [rightList, rightRef, setRightList] = useList()
|
18
|
|
- const vidRef = useRef()
|
19
|
|
- const [cursor, setCursor] = useState(-1)
|
|
19
|
+ const [cursor, setCursor] = useState(0)
|
20
|
20
|
|
21
|
21
|
const listRef = useRef([])
|
22
|
22
|
listRef.current = list
|
23
|
|
-
|
24
|
|
- useEffect(() => {
|
25
|
|
- if (list && list.length) {
|
26
|
|
- setCursor(0)
|
|
23
|
+
|
|
24
|
+ const handleRenderFinish = (direct) => (rect) => {
|
|
25
|
+ const { bottom } = rect
|
|
26
|
+
|
|
27
|
+ if (direct === 'left') {
|
|
28
|
+ leftBottom.current = bottom
|
27
|
29
|
} else {
|
28
|
|
- setCursor(-1)
|
29
|
|
- setLeftList([])
|
30
|
|
- setRightList([])
|
|
30
|
+ rightBottom.current = bottom
|
31
|
31
|
}
|
32
|
|
- }, [list])
|
33
|
32
|
|
|
33
|
+ setCursor(cursor + 1)
|
|
34
|
+ }
|
|
35
|
+
|
34
|
36
|
useEffect(() => {
|
35
|
|
- const len = !listRef.current ? 0 : listRef.current.length;
|
|
37
|
+ setCursor(0)
|
|
38
|
+ setLeftList([])
|
|
39
|
+ setRightList([])
|
|
40
|
+ listRef.current = list ? list.slice() : []
|
|
41
|
+ }, [list])
|
36
|
42
|
|
|
43
|
+ useEffect(() => {
|
|
44
|
+ const len = !list ? 0 : list.length;
|
37
|
45
|
if (leftRef.current.length + rightRef.current.length >= len) return;
|
38
|
46
|
|
39
|
|
- const item = listRef.current[cursor] || {}
|
|
47
|
+ const item = listRef.current.shift()
|
40
|
48
|
item.__vid = `f-${Math.random().toString(36).substring(2)}`
|
41
|
|
- vidRef.current = item.__vid
|
42
|
49
|
|
43
|
50
|
if (leftBottom.current <= rightBottom.current) {
|
44
|
51
|
setLeftList([...leftRef.current, item])
|
45
|
52
|
} else {
|
46
|
53
|
setRightList([...rightRef.current, item])
|
47
|
54
|
}
|
48
|
|
- }, [cursor])
|
49
|
|
-
|
50
|
|
- useEffect(() => {
|
51
|
|
- const setHeight = (rect) => {
|
52
|
|
- const { bottom } = rect
|
53
|
|
- if (cursor % 2 === 0) {
|
54
|
|
- leftBottom.current = bottom
|
55
|
|
- } else {
|
56
|
|
- rightBottom.current = bottom
|
57
|
|
- }
|
58
|
|
- setCursor(cursor + 1)
|
59
|
|
- }
|
60
|
|
-
|
61
|
|
- const calcHeight = () => {
|
62
|
|
- getRect(`.${vidRef.current}`).then((res) => {
|
63
|
|
- if (!res) {
|
64
|
|
- // 找不到 node , 则一直重复查询
|
65
|
|
- const t = setTimeout(() => {
|
66
|
|
- clearTimeout(t)
|
67
|
|
- calcHeight()
|
68
|
|
- }, 300)
|
69
|
|
- } else {
|
70
|
|
- if (Array.isArray(res)) {
|
71
|
|
- setHeight(res[0])
|
72
|
|
- } else {
|
73
|
|
- setHeight(res)
|
74
|
|
- }
|
75
|
|
- }
|
76
|
|
- })
|
77
|
|
- }
|
78
|
|
-
|
79
|
|
- calcHeight()
|
80
|
|
- })
|
|
55
|
+ }, [cursor, list])
|
81
|
56
|
|
82
|
57
|
return (
|
83
|
58
|
<View
|
84
|
|
- className={classNames(className, 'masonry-layout')}
|
85
|
59
|
style={style}
|
|
60
|
+ className={classNames(className, 'masonry-layout')}
|
86
|
61
|
>
|
87
|
62
|
<View className='masonry-column'>
|
88
|
63
|
{
|
89
|
|
- leftList.map((item) => (
|
90
|
|
- <View key={item.__vid} className={classNames(itemClassName, 'masonry-item', item.__vid)}>{render(item)}</View>
|
91
|
|
- ))
|
|
64
|
+ leftList.map(item => <Item key={item.__vid} className={itemClassName} item={item} render={render} onRenderFinish={handleRenderFinish('left')} />)
|
92
|
65
|
}
|
93
|
66
|
</View>
|
94
|
67
|
<View className='masonry-split' style={splitStyle} />
|
95
|
68
|
<View className='masonry-column'>
|
96
|
69
|
{
|
97
|
|
- rightList.map((item) => (
|
98
|
|
- <View key={item.__vid} className={classNames(itemClassName, 'masonry-item', item.__vid)}>{render(item)}</View>
|
99
|
|
- ))
|
|
70
|
+ rightList.map(item => <Item key={item.__vid} className={itemClassName} item={item} render={render} onRenderFinish={handleRenderFinish('right')} />)
|
100
|
71
|
}
|
101
|
72
|
</View>
|
102
|
73
|
</View>
|