@@ -4,6 +4,7 @@ import useRect from './useRect'
44import useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect'
55
66const defaultEstimateSize = ( ) => 50
7+ const defaultKeyExtractor = index => index
78
89export function useVirtual ( {
910 size = 0 ,
@@ -17,6 +18,7 @@ export function useVirtual({
1718 useObserver,
1819 onScrollElement,
1920 scrollOffsetFn,
21+ keyExtractor = defaultKeyExtractor ,
2022} ) {
2123 const sizeKey = horizontal ? 'width' : 'height'
2224 const scrollKey = horizontal ? 'scrollLeft' : 'scrollTop'
@@ -47,23 +49,20 @@ export function useVirtual({
4749
4850 const [ measuredCache , setMeasuredCache ] = React . useState ( { } )
4951
50- const measure = React . useCallback (
51- ( ) => setMeasuredCache ( { } ) ,
52- [ ]
53- )
52+ const measure = React . useCallback ( ( ) => setMeasuredCache ( { } ) , [ ] )
5453
5554 const measurements = React . useMemo ( ( ) => {
5655 const measurements = [ ]
5756 for ( let i = 0 ; i < size ; i ++ ) {
58- const measuredSize = measuredCache [ i ]
57+ const measuredSize = measuredCache [ keyExtractor ( i ) ]
5958 const start = measurements [ i - 1 ] ? measurements [ i - 1 ] . end : paddingStart
6059 const size =
6160 typeof measuredSize === 'number' ? measuredSize : estimateSize ( i )
6261 const end = start + size
6362 measurements [ i ] = { index : i , start, size, end }
6463 }
6564 return measurements
66- } , [ estimateSize , measuredCache , paddingStart , size ] )
65+ } , [ estimateSize , measuredCache , paddingStart , size , keyExtractor ] )
6766
6867 const totalSize = ( measurements [ size - 1 ] ?. end || 0 ) + paddingEnd
6968
@@ -78,10 +77,14 @@ export function useVirtual({
7877
7978 const element = onScrollElement ? onScrollElement . current : parentRef . current
8079 useIsomorphicLayoutEffect ( ( ) => {
81- if ( ! element ) { return }
80+ if ( ! element ) {
81+ return
82+ }
8283
8384 const onScroll = ( ) => {
84- const scrollOffset = scrollOffsetFn ? scrollOffsetFn ( ) : element [ scrollKey ]
85+ const scrollOffset = scrollOffsetFn
86+ ? scrollOffsetFn ( )
87+ : element [ scrollKey ]
8588 latestRef . current . scrollOffset = scrollOffset
8689 setRange ( prevRange => calculateRange ( latestRef . current , prevRange ) )
8790 }
@@ -121,7 +124,7 @@ export function useVirtual({
121124
122125 setMeasuredCache ( old => ( {
123126 ...old ,
124- [ i ] : measuredSize ,
127+ [ keyExtractor ( i ) ] : measuredSize ,
125128 } ) )
126129 }
127130 }
@@ -132,16 +135,23 @@ export function useVirtual({
132135 }
133136
134137 return virtualItems
135- } , [ range . start , range . end , measurements , sizeKey , defaultScrollToFn ] )
138+ } , [
139+ range . start ,
140+ range . end ,
141+ measurements ,
142+ sizeKey ,
143+ defaultScrollToFn ,
144+ keyExtractor ,
145+ ] )
136146
137147 const mountedRef = React . useRef ( )
138148
139149 useIsomorphicLayoutEffect ( ( ) => {
140150 if ( mountedRef . current ) {
141- if ( estimateSize || size ) setMeasuredCache ( { } )
151+ if ( estimateSize ) setMeasuredCache ( { } )
142152 }
143153 mountedRef . current = true
144- } , [ estimateSize , size ] )
154+ } , [ estimateSize ] )
145155
146156 const scrollToOffset = React . useCallback (
147157 ( toOffset , { align = 'start' } = { } ) => {
@@ -192,8 +202,8 @@ export function useVirtual({
192202 align === 'center'
193203 ? measurement . start + measurement . size / 2
194204 : align === 'end'
195- ? measurement . end
196- : measurement . start
205+ ? measurement . end
206+ : measurement . start
197207
198208 scrollToOffset ( toOffset , { align, ...rest } )
199209 } ,
@@ -224,19 +234,20 @@ export function useVirtual({
224234 }
225235}
226236
227- function calculateRange ( {
228- overscan,
229- measurements,
230- outerSize,
231- scrollOffset,
232- } , prevRange ) {
237+ function calculateRange (
238+ { overscan, measurements, outerSize, scrollOffset } ,
239+ prevRange
240+ ) {
233241 const total = measurements . length
234242 let start = total - 1
235243 while ( start > 0 && measurements [ start ] . end >= scrollOffset ) {
236244 start -= 1
237245 }
238246 let end = 0
239- while ( end < total - 1 && measurements [ end ] . start <= scrollOffset + outerSize ) {
247+ while (
248+ end < total - 1 &&
249+ measurements [ end ] . start <= scrollOffset + outerSize
250+ ) {
240251 end += 1
241252 }
242253
0 commit comments