@@ -22,6 +22,12 @@ interface ListState {
22
22
itemOffsetPtg : number ;
23
23
startIndex : number ;
24
24
endIndex : number ;
25
+ /**
26
+ * Calculated by `scrollTop`.
27
+ * We cache in the state since if `dataSource` length change,
28
+ * we need revert back to the located item index.
29
+ */
30
+ startItemTop : number ;
25
31
}
26
32
27
33
/**
@@ -48,6 +54,7 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
48
54
itemOffsetPtg : 0 ,
49
55
startIndex : 0 ,
50
56
endIndex : 0 ,
57
+ startItemTop : 0 ,
51
58
} ;
52
59
53
60
listRef = React . createRef < HTMLElement > ( ) ;
@@ -69,7 +76,7 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
69
76
* Phase 5: Trigger re-render to use correct position
70
77
*/
71
78
public componentDidUpdate ( prevProps : ListProps < T > ) {
72
- const { status, startIndex, endIndex } = this . state ;
79
+ const { status, scrollPtg , startIndex, endIndex, itemIndex , itemOffsetPtg } = this . state ;
73
80
const { dataSource, itemKey } = this . props ;
74
81
75
82
if ( status === 'MEASURE_START' ) {
@@ -80,7 +87,19 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
80
87
this . itemElementHeights [ index ] = getNodeHeight ( this . itemElements [ eleKey ] ) ;
81
88
}
82
89
83
- this . setState ( { status : 'MEASURE_DONE' } ) ;
90
+ // Calculate top visible item top offset
91
+ const locatedItemHeight = this . getItemHeight ( itemIndex ) ;
92
+ const locatedItemTop = scrollPtg * this . listRef . current . clientHeight ;
93
+ const locatedItemOffset = itemOffsetPtg * locatedItemHeight ;
94
+ const locatedItemMergedTop =
95
+ this . listRef . current . scrollTop + locatedItemTop - locatedItemOffset ;
96
+
97
+ let startItemTop = locatedItemMergedTop ;
98
+ for ( let index = itemIndex - 1 ; index >= startIndex ; index -= 1 ) {
99
+ startItemTop -= this . getItemHeight ( index ) ;
100
+ }
101
+
102
+ this . setState ( { status : 'MEASURE_DONE' , startItemTop } ) ;
84
103
}
85
104
86
105
// Re-calculate the scroll position align with the current visible item position
@@ -165,25 +184,9 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
165
184
) ;
166
185
}
167
186
168
- const { status, startIndex, endIndex, itemIndex, itemOffsetPtg, scrollPtg } = this . state ;
169
-
187
+ const { status, startIndex, endIndex, startItemTop } = this . state ;
170
188
const contentHeight = dataSource . length * itemHeight ;
171
189
172
- // TODO: refactor
173
- let startItemTop = 0 ;
174
- if ( status === 'MEASURE_DONE' ) {
175
- const locatedItemHeight = this . getItemHeight ( itemIndex ) ;
176
- const locatedItemTop = scrollPtg * this . listRef . current . clientHeight ;
177
- const locatedItemOffset = itemOffsetPtg * locatedItemHeight ;
178
- const locatedItemMergedTop =
179
- this . listRef . current . scrollTop + locatedItemTop - locatedItemOffset ;
180
-
181
- startItemTop = locatedItemMergedTop ;
182
- for ( let index = itemIndex - 1 ; index >= startIndex ; index -= 1 ) {
183
- startItemTop -= this . getItemHeight ( index ) ;
184
- }
185
- }
186
-
187
190
return (
188
191
< Component
189
192
style = { {
0 commit comments