virtual-scroller 1.11.2 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.md +13 -11
- package/bundle/virtual-scroller-dom.js +1 -1
- package/bundle/virtual-scroller-dom.js.map +1 -1
- package/bundle/virtual-scroller-react.js +1 -1
- package/bundle/virtual-scroller-react.js.map +1 -1
- package/bundle/virtual-scroller.js +1 -1
- package/bundle/virtual-scroller.js.map +1 -1
- package/commonjs/DOM/ItemsContainer.js +10 -3
- package/commonjs/DOM/ItemsContainer.js.map +1 -1
- package/commonjs/DOM/VirtualScroller.js +13 -1
- package/commonjs/DOM/VirtualScroller.js.map +1 -1
- package/commonjs/ItemHeights.js +5 -5
- package/commonjs/ItemHeights.js.map +1 -1
- package/commonjs/ItemNotRenderedError.js +64 -0
- package/commonjs/ItemNotRenderedError.js.map +1 -0
- package/commonjs/Layout.test.js +10 -0
- package/commonjs/Layout.test.js.map +1 -1
- package/commonjs/VirtualScroller.js +23 -5
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +81 -39
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.onRender.js +97 -45
- package/commonjs/VirtualScroller.onRender.js.map +1 -1
- package/commonjs/VirtualScroller.state.js +50 -18
- package/commonjs/VirtualScroller.state.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +31 -46
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/useItemKeys.js +11 -3
- package/commonjs/react/useItemKeys.js.map +1 -1
- package/commonjs/react/useOnChange.js +19 -0
- package/commonjs/react/useOnChange.js.map +1 -0
- package/commonjs/react/{useOnItemHeightChange.js → useOnItemHeightDidChange.js} +7 -7
- package/commonjs/react/useOnItemHeightDidChange.js.map +1 -0
- package/commonjs/react/{useHandleItemsPropertyChange.js → useSetNewItemsOnItemsPropertyChange.js} +15 -14
- package/commonjs/react/useSetNewItemsOnItemsPropertyChange.js.map +1 -0
- package/commonjs/react/useState.js +162 -69
- package/commonjs/react/useState.js.map +1 -1
- package/commonjs/react/useStyle.js +3 -5
- package/commonjs/react/useStyle.js.map +1 -1
- package/commonjs/react/useUpdateItemKeysOnItemsChange.js +61 -0
- package/commonjs/react/useUpdateItemKeysOnItemsChange.js.map +1 -0
- package/commonjs/test/ItemsContainer.js +22 -1
- package/commonjs/test/ItemsContainer.js.map +1 -1
- package/commonjs/utility/debug.js +30 -6
- package/commonjs/utility/debug.js.map +1 -1
- package/dom/index.d.ts +1 -1
- package/index.cjs +2 -0
- package/index.d.ts +7 -1
- package/index.js +1 -0
- package/modules/DOM/ItemsContainer.js +8 -3
- package/modules/DOM/ItemsContainer.js.map +1 -1
- package/modules/DOM/VirtualScroller.js +13 -1
- package/modules/DOM/VirtualScroller.js.map +1 -1
- package/modules/ItemHeights.js +5 -5
- package/modules/ItemHeights.js.map +1 -1
- package/modules/ItemNotRenderedError.js +57 -0
- package/modules/ItemNotRenderedError.js.map +1 -0
- package/modules/Layout.test.js +10 -0
- package/modules/Layout.test.js.map +1 -1
- package/modules/VirtualScroller.js +17 -5
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +78 -39
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.onRender.js +98 -46
- package/modules/VirtualScroller.onRender.js.map +1 -1
- package/modules/VirtualScroller.state.js +50 -18
- package/modules/VirtualScroller.state.js.map +1 -1
- package/modules/react/VirtualScroller.js +31 -46
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/useItemKeys.js +8 -3
- package/modules/react/useItemKeys.js.map +1 -1
- package/modules/react/useOnChange.js +11 -0
- package/modules/react/useOnChange.js.map +1 -0
- package/modules/react/{useOnItemHeightChange.js → useOnItemHeightDidChange.js} +6 -6
- package/modules/react/useOnItemHeightDidChange.js.map +1 -0
- package/modules/react/{useHandleItemsPropertyChange.js → useSetNewItemsOnItemsPropertyChange.js} +11 -13
- package/modules/react/useSetNewItemsOnItemsPropertyChange.js.map +1 -0
- package/modules/react/useState.js +156 -73
- package/modules/react/useState.js.map +1 -1
- package/modules/react/useStyle.js +3 -5
- package/modules/react/useStyle.js.map +1 -1
- package/{commonjs/react/useHandleItemIndexesChange.js → modules/react/useUpdateItemKeysOnItemsChange.js} +18 -21
- package/modules/react/useUpdateItemKeysOnItemsChange.js.map +1 -0
- package/modules/test/ItemsContainer.js +20 -1
- package/modules/test/ItemsContainer.js.map +1 -1
- package/modules/utility/debug.js +31 -6
- package/modules/utility/debug.js.map +1 -1
- package/package.json +1 -1
- package/source/DOM/ItemsContainer.js +8 -3
- package/source/DOM/VirtualScroller.js +11 -1
- package/source/ItemHeights.js +5 -5
- package/source/ItemNotRenderedError.js +16 -0
- package/source/Layout.test.js +9 -0
- package/source/VirtualScroller.js +14 -3
- package/source/VirtualScroller.layout.js +77 -38
- package/source/VirtualScroller.onRender.js +95 -42
- package/source/VirtualScroller.state.js +57 -20
- package/source/react/VirtualScroller.js +28 -39
- package/source/react/useItemKeys.js +9 -2
- package/source/react/useOnChange.js +11 -0
- package/source/react/{useOnItemHeightChange.js → useOnItemHeightDidChange.js} +5 -5
- package/source/react/{useHandleItemsPropertyChange.js → useSetNewItemsOnItemsPropertyChange.js} +11 -11
- package/source/react/useState.js +159 -71
- package/source/react/useStyle.js +2 -2
- package/source/react/{useHandleItemIndexesChange.js → useUpdateItemKeysOnItemsChange.js} +17 -9
- package/source/test/ItemsContainer.js +22 -1
- package/source/utility/debug.js +18 -4
- package/commonjs/react/useHandleItemIndexesChange.js.map +0 -1
- package/commonjs/react/useHandleItemsPropertyChange.js.map +0 -1
- package/commonjs/react/useOnItemHeightChange.js.map +0 -1
- package/modules/react/useHandleItemIndexesChange.js +0 -45
- package/modules/react/useHandleItemIndexesChange.js.map +0 -1
- package/modules/react/useHandleItemsPropertyChange.js.map +0 -1
- package/modules/react/useOnItemHeightChange.js.map +0 -1
|
@@ -52,7 +52,13 @@ export default function createStateHelpers({
|
|
|
52
52
|
|
|
53
53
|
this.getState().itemStates[i] = newItemState
|
|
54
54
|
|
|
55
|
-
//
|
|
55
|
+
// If there was a request for `setState()` with new `items`, then the changes
|
|
56
|
+
// to `currentState.itemStates[]` made above would be overwritten when that
|
|
57
|
+
// pending `setState()` call gets applied.
|
|
58
|
+
// To fix that, the updates to current `itemStates[]` are noted in
|
|
59
|
+
// `this.itemStatesThatChangedWhileNewItemsWereBeingRendered` variable.
|
|
60
|
+
// That variable is then checked when the `setState()` call with the new `items`
|
|
61
|
+
// has been updated.
|
|
56
62
|
if (this.newItemsWillBeRendered) {
|
|
57
63
|
if (!this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {
|
|
58
64
|
this.itemStatesThatChangedWhileNewItemsWereBeingRendered = {}
|
|
@@ -78,9 +84,25 @@ export default function createStateHelpers({
|
|
|
78
84
|
}
|
|
79
85
|
this._isSettingNewItems = undefined
|
|
80
86
|
|
|
81
|
-
|
|
87
|
+
this.waitingForRender = true
|
|
88
|
+
|
|
89
|
+
// Store previous `state`.
|
|
82
90
|
this.previousState = this.getState()
|
|
83
|
-
|
|
91
|
+
|
|
92
|
+
// If it's the first call to `this.updateState()` then initialize
|
|
93
|
+
// the most recent `setState()` value to be the current state.
|
|
94
|
+
if (!this.mostRecentSetStateValue) {
|
|
95
|
+
this.mostRecentSetStateValue = this.getState()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Accumulates all "pending" state updates until they have been applied.
|
|
99
|
+
this.mostRecentSetStateValue = {
|
|
100
|
+
...this.mostRecentSetStateValue,
|
|
101
|
+
...stateUpdate
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Update `state`.
|
|
105
|
+
this._setState(this.mostRecentSetStateValue, stateUpdate)
|
|
84
106
|
}
|
|
85
107
|
|
|
86
108
|
this.getInitialState = () => {
|
|
@@ -92,6 +114,7 @@ export default function createStateHelpers({
|
|
|
92
114
|
|
|
93
115
|
this.useState = ({
|
|
94
116
|
getState,
|
|
117
|
+
setState,
|
|
95
118
|
updateState
|
|
96
119
|
}) => {
|
|
97
120
|
if (this._isActive) {
|
|
@@ -103,17 +126,28 @@ export default function createStateHelpers({
|
|
|
103
126
|
}
|
|
104
127
|
|
|
105
128
|
if (render) {
|
|
106
|
-
throw new Error('[virtual-scroller] Creating a `VirtualScroller` class instance with a `render()` parameter
|
|
129
|
+
throw new Error('[virtual-scroller] Creating a `VirtualScroller` class instance with a `render()` parameter implies using the default (internal) state storage')
|
|
107
130
|
}
|
|
108
131
|
|
|
109
|
-
if (
|
|
110
|
-
throw new Error('[virtual-scroller] When using a custom state storage, one must supply
|
|
132
|
+
if (setState && updateState) {
|
|
133
|
+
throw new Error('[virtual-scroller] When using a custom state storage, one must supply either `setState()` or `updateState()` function but not both')
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!getState || !(setState || updateState)) {
|
|
137
|
+
throw new Error('[virtual-scroller] When using a custom state storage, one must supply both `getState()` and `setState()`/`updateState()` functions')
|
|
111
138
|
}
|
|
112
139
|
|
|
113
140
|
this._usesCustomStateStorage = true
|
|
114
141
|
|
|
115
142
|
this._getState = getState
|
|
116
|
-
|
|
143
|
+
|
|
144
|
+
this._setState = (newState, stateUpdate) => {
|
|
145
|
+
if (setState) {
|
|
146
|
+
setState(newState)
|
|
147
|
+
} else {
|
|
148
|
+
updateState(stateUpdate)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
117
151
|
}
|
|
118
152
|
|
|
119
153
|
this.useDefaultStateStorage = () => {
|
|
@@ -121,9 +155,9 @@ export default function createStateHelpers({
|
|
|
121
155
|
throw new Error('[virtual-scroller] When using the default (internal) state management, one must supply a `render(state, prevState)` function parameter')
|
|
122
156
|
}
|
|
123
157
|
|
|
124
|
-
// Create default `getState()`/`
|
|
158
|
+
// Create default `getState()`/`setState()` functions.
|
|
125
159
|
this._getState = defaultGetState.bind(this)
|
|
126
|
-
this.
|
|
160
|
+
this._setState = defaultSetState.bind(this)
|
|
127
161
|
|
|
128
162
|
// When `state` is stored externally, a developer is responsible for
|
|
129
163
|
// initializing it with the initial value.
|
|
@@ -140,17 +174,20 @@ export default function createStateHelpers({
|
|
|
140
174
|
this.state = newState
|
|
141
175
|
}
|
|
142
176
|
|
|
143
|
-
function
|
|
144
|
-
// Because
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
this.state
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
177
|
+
function defaultSetState(newState, stateUpdate) {
|
|
178
|
+
// // Because the default state updates are "synchronous" (immediate),
|
|
179
|
+
// // the `...stateUpdate` could be applied over `...this.state`,
|
|
180
|
+
// // and no state updates would be lost.
|
|
181
|
+
// // But if it was "asynchronous" (not immediate), then `...this.state`
|
|
182
|
+
// // wouldn't work in all cases, because it could be stale in cases
|
|
183
|
+
// // when more than a single `setState()` call is made before
|
|
184
|
+
// // the state actually updates, making some properties of `this.state` stale.
|
|
185
|
+
// this.state = {
|
|
186
|
+
// ...this.state,
|
|
187
|
+
// ...stateUpdate
|
|
188
|
+
// }
|
|
189
|
+
|
|
190
|
+
this.state = newState
|
|
154
191
|
|
|
155
192
|
render(this.state, this.previousState)
|
|
156
193
|
|
|
@@ -7,33 +7,22 @@ import useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js'
|
|
|
7
7
|
import useInstanceMethods from './useInstanceMethods.js'
|
|
8
8
|
import useItemKeys from './useItemKeys.js'
|
|
9
9
|
import useSetItemState from './useSetItemState.js'
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
10
|
+
import useOnItemHeightDidChange from './useOnItemHeightDidChange.js'
|
|
11
|
+
import useSetNewItemsOnItemsPropertyChange from './useSetNewItemsOnItemsPropertyChange.js'
|
|
12
|
+
import useUpdateItemKeysOnItemsChange from './useUpdateItemKeysOnItemsChange.js'
|
|
13
13
|
import useClassName from './useClassName.js'
|
|
14
14
|
import useStyle from './useStyle.js'
|
|
15
15
|
|
|
16
|
-
// When `items` property changes
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// Another reason for using this feature is:
|
|
28
|
-
//
|
|
29
|
-
// Since `useHandleItemsPropertyChange()` runs at render time
|
|
30
|
-
// and not after the render has finished (not in an "effect"),
|
|
31
|
-
// if the state update was done "conventionally" (by calling `_setNewState()`),
|
|
32
|
-
// React would throw an error about updating state during render.
|
|
33
|
-
// No one knows what the original error message was.
|
|
34
|
-
// Perhaps it's no longer relevant in newer versions of React.
|
|
35
|
-
//
|
|
36
|
-
const USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true
|
|
16
|
+
// When `items` property changes:
|
|
17
|
+
// * A new `items` property is supplied to the React component.
|
|
18
|
+
// * The React component re-renders itself.
|
|
19
|
+
// * `useSetNewItemsOnItemsPropertyChange()` hook is run.
|
|
20
|
+
// * `useSetNewItemsOnItemsPropertyChange()` hook detects that the `items` property
|
|
21
|
+
// has changed and calls `VirtualScroller.setItems(items)`.
|
|
22
|
+
// * `VirtualScroller.setItems(items)` calls `VirtualScroller.setState()`.
|
|
23
|
+
// * `VirtualScroller.setState()` calls the `setState()` function.
|
|
24
|
+
// * The `setState()` function calls a setter from a `useState()` hook.
|
|
25
|
+
// * The React component re-renders itself the second time.
|
|
37
26
|
|
|
38
27
|
function VirtualScroller({
|
|
39
28
|
as: AsComponent,
|
|
@@ -113,20 +102,19 @@ function VirtualScroller({
|
|
|
113
102
|
// This way, React will re-render the component on every state update.
|
|
114
103
|
const {
|
|
115
104
|
getState,
|
|
116
|
-
|
|
117
|
-
|
|
105
|
+
setState,
|
|
106
|
+
stateToRender
|
|
118
107
|
} = useState({
|
|
119
108
|
initialState: _initialState,
|
|
120
109
|
onRender: virtualScroller.onRender,
|
|
121
|
-
itemsProperty
|
|
122
|
-
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
|
|
110
|
+
itemsProperty
|
|
123
111
|
})
|
|
124
112
|
|
|
125
113
|
// Use custom (external) state storage in the `VirtualScroller`.
|
|
126
114
|
useMemo(() => {
|
|
127
115
|
virtualScroller.useState({
|
|
128
116
|
getState,
|
|
129
|
-
|
|
117
|
+
setState
|
|
130
118
|
})
|
|
131
119
|
}, [])
|
|
132
120
|
|
|
@@ -138,6 +126,7 @@ function VirtualScroller({
|
|
|
138
126
|
// "reuse" `itemComponent`s in cases when `items` are changed.
|
|
139
127
|
const {
|
|
140
128
|
getItemKey,
|
|
129
|
+
usesAutogeneratedItemKeys,
|
|
141
130
|
updateItemKeysForNewItems
|
|
142
131
|
} = useItemKeys({
|
|
143
132
|
getItemId
|
|
@@ -150,27 +139,26 @@ function VirtualScroller({
|
|
|
150
139
|
virtualScroller
|
|
151
140
|
})
|
|
152
141
|
|
|
153
|
-
// Cache per-item `
|
|
142
|
+
// Cache per-item `onItemHeightDidChange` functions' "references"
|
|
154
143
|
// so that item components don't get re-rendered needlessly.
|
|
155
|
-
const
|
|
144
|
+
const getOnItemHeightDidChange = useOnItemHeightDidChange({
|
|
156
145
|
initialItemsCount: itemsProperty.length,
|
|
157
146
|
virtualScroller
|
|
158
147
|
})
|
|
159
148
|
|
|
160
149
|
// Calls `.setItems()` if `items` property has changed.
|
|
161
|
-
|
|
150
|
+
useSetNewItemsOnItemsPropertyChange(itemsProperty, {
|
|
162
151
|
virtualScroller,
|
|
163
152
|
// `preserveScrollPosition` property name is deprecated,
|
|
164
153
|
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
165
154
|
preserveScrollPosition,
|
|
166
|
-
preserveScrollPositionOnPrependItems
|
|
167
|
-
nextItems: getNextState().items
|
|
155
|
+
preserveScrollPositionOnPrependItems
|
|
168
156
|
})
|
|
169
157
|
|
|
170
158
|
// Updates `key`s if item indexes have changed.
|
|
171
|
-
|
|
159
|
+
useUpdateItemKeysOnItemsChange(stateToRender.items, {
|
|
172
160
|
virtualScroller,
|
|
173
|
-
|
|
161
|
+
usesAutogeneratedItemKeys,
|
|
174
162
|
updateItemKeysForNewItems
|
|
175
163
|
})
|
|
176
164
|
|
|
@@ -209,7 +197,7 @@ function VirtualScroller({
|
|
|
209
197
|
|
|
210
198
|
const style = useStyle({
|
|
211
199
|
tbody,
|
|
212
|
-
|
|
200
|
+
state: stateToRender
|
|
213
201
|
})
|
|
214
202
|
|
|
215
203
|
const {
|
|
@@ -217,7 +205,7 @@ function VirtualScroller({
|
|
|
217
205
|
itemStates,
|
|
218
206
|
firstShownItemIndex,
|
|
219
207
|
lastShownItemIndex
|
|
220
|
-
} =
|
|
208
|
+
} = stateToRender
|
|
221
209
|
|
|
222
210
|
return (
|
|
223
211
|
<AsComponent
|
|
@@ -251,7 +239,8 @@ function VirtualScroller({
|
|
|
251
239
|
state={itemStates && itemStates[i]}
|
|
252
240
|
setState={getSetItemState(i)}
|
|
253
241
|
onStateChange={getSetItemState(i)}
|
|
254
|
-
onHeightChange={
|
|
242
|
+
onHeightChange={getOnItemHeightDidChange(i)}
|
|
243
|
+
onHeightDidChange={getOnItemHeightDidChange(i)}>
|
|
255
244
|
{item}
|
|
256
245
|
</Component>
|
|
257
246
|
)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import log from '../utility/debug.js'
|
|
2
|
+
|
|
1
3
|
import { useRef, useMemo, useCallback } from 'react'
|
|
2
4
|
|
|
3
5
|
export default function useItemKeys({ getItemId }) {
|
|
@@ -27,12 +29,16 @@ export default function useItemKeys({ getItemId }) {
|
|
|
27
29
|
generateItemKeyPrefix()
|
|
28
30
|
}, [])
|
|
29
31
|
|
|
32
|
+
// If `getItemId()` function is defined, then item `id`s are gonna be the item element `key`s.
|
|
33
|
+
const usesAutogeneratedItemKeys = !getItemId
|
|
34
|
+
|
|
30
35
|
const generateItemKeyPrefixIfNotUsingItemIds = useCallback(() => {
|
|
31
|
-
if (
|
|
36
|
+
if (usesAutogeneratedItemKeys) {
|
|
32
37
|
generateItemKeyPrefix()
|
|
38
|
+
log('React: ~ Item key prefix:', itemKeyPrefix.current)
|
|
33
39
|
}
|
|
34
40
|
}, [
|
|
35
|
-
|
|
41
|
+
usesAutogeneratedItemKeys,
|
|
36
42
|
generateItemKeyPrefix
|
|
37
43
|
])
|
|
38
44
|
|
|
@@ -54,6 +60,7 @@ export default function useItemKeys({ getItemId }) {
|
|
|
54
60
|
|
|
55
61
|
return {
|
|
56
62
|
getItemKey,
|
|
63
|
+
usesAutogeneratedItemKeys,
|
|
57
64
|
updateItemKeysForNewItems: generateItemKeyPrefixIfNotUsingItemIds
|
|
58
65
|
}
|
|
59
66
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
export default function useOnChange(value, onChange) {
|
|
4
|
+
const previousValueRef = useRef(value)
|
|
5
|
+
const previousValue = previousValueRef.current
|
|
6
|
+
previousValueRef.current = value
|
|
7
|
+
|
|
8
|
+
if (value !== previousValue) {
|
|
9
|
+
onChange(value, previousValue)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMemo, useRef, useCallback } from 'react'
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function useOnItemHeightDidChange({
|
|
4
4
|
initialItemsCount,
|
|
5
5
|
virtualScroller
|
|
6
6
|
}) {
|
|
@@ -12,11 +12,11 @@ export default function useOnItemHeightChange({
|
|
|
12
12
|
// Handler functions cache.
|
|
13
13
|
const cache = useRef(initialCacheValue)
|
|
14
14
|
|
|
15
|
-
// Caches per-item `
|
|
15
|
+
// Caches per-item `onItemHeightDidChange` functions' "references"
|
|
16
16
|
// so that item components don't get re-rendered needlessly.
|
|
17
|
-
const
|
|
17
|
+
const getOnItemHeightDidChange = useCallback((i) => {
|
|
18
18
|
if (!cache.current[i]) {
|
|
19
|
-
cache.current[i] = () => virtualScroller.
|
|
19
|
+
cache.current[i] = () => virtualScroller.onItemHeightDidChange(i)
|
|
20
20
|
}
|
|
21
21
|
return cache.current[i]
|
|
22
22
|
}, [
|
|
@@ -24,5 +24,5 @@ export default function useOnItemHeightChange({
|
|
|
24
24
|
cache
|
|
25
25
|
])
|
|
26
26
|
|
|
27
|
-
return
|
|
27
|
+
return getOnItemHeightDidChange
|
|
28
28
|
}
|
package/source/react/{useHandleItemsPropertyChange.js → useSetNewItemsOnItemsPropertyChange.js}
RENAMED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import log from '../utility/debug.js'
|
|
2
|
+
|
|
3
|
+
import useOnChange from './useOnChange.js'
|
|
2
4
|
|
|
3
5
|
// If new `items` property is passed:
|
|
4
6
|
//
|
|
@@ -8,13 +10,12 @@ import { useRef } from 'react'
|
|
|
8
10
|
//
|
|
9
11
|
// * Call `VirtualScroller.setItems()` function.
|
|
10
12
|
//
|
|
11
|
-
export default function
|
|
13
|
+
export default function useSetNewItemsOnItemsPropertyChange(itemsProperty, {
|
|
12
14
|
virtualScroller,
|
|
13
15
|
// `preserveScrollPosition` property name is deprecated,
|
|
14
16
|
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
15
17
|
preserveScrollPosition,
|
|
16
|
-
preserveScrollPositionOnPrependItems
|
|
17
|
-
nextItems
|
|
18
|
+
preserveScrollPositionOnPrependItems
|
|
18
19
|
}) {
|
|
19
20
|
// During render, check if the `items` list has changed.
|
|
20
21
|
// If it has, capture the Y scroll position and updated item element `key`s.
|
|
@@ -60,15 +61,13 @@ export default function useHandleItemsPropertyChange(itemsProperty, {
|
|
|
60
61
|
// scroll Y position is captured while the "Show previous" button
|
|
61
62
|
// is still being shown.
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
previousItemsProperty.current = itemsProperty
|
|
64
|
+
useOnChange(itemsProperty, (itemsProperty, prevItemsProperty) => {
|
|
65
|
+
log('React: ~ Different `items` property has been passed', itemsProperty)
|
|
66
66
|
|
|
67
|
-
if (hasItemsPropertyChanged) {
|
|
68
67
|
let shouldUpdateItems = true
|
|
69
68
|
|
|
70
69
|
// Analyze the upcoming `items` change.
|
|
71
|
-
const itemsDiff = virtualScroller.getItemsDiff(
|
|
70
|
+
const itemsDiff = virtualScroller.getItemsDiff(prevItemsProperty, itemsProperty)
|
|
72
71
|
|
|
73
72
|
// `itemsDiff` will be `undefined` in case of a non-incremental items list change.
|
|
74
73
|
if (itemsDiff) {
|
|
@@ -79,12 +78,13 @@ export default function useHandleItemsPropertyChange(itemsProperty, {
|
|
|
79
78
|
if (prependedItemsCount === 0 && appendedItemsCount === 0) {
|
|
80
79
|
// The items order hasn't changed.
|
|
81
80
|
// No need to update them in `VirtualScroller` or to snapshot the Y scroll position.
|
|
81
|
+
log('React: ~ The `items` elements are identical to the previous ones')
|
|
82
82
|
shouldUpdateItems = false
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
if (shouldUpdateItems) {
|
|
87
|
-
//
|
|
87
|
+
// Make a request to update the `items` in `VirtualScroller`.
|
|
88
88
|
// This will result in a `setState()` call.
|
|
89
89
|
// The new items won't be rendered until that state update is applied.
|
|
90
90
|
virtualScroller.setItems(itemsProperty, {
|
|
@@ -93,5 +93,5 @@ export default function useHandleItemsPropertyChange(itemsProperty, {
|
|
|
93
93
|
preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems || preserveScrollPosition
|
|
94
94
|
})
|
|
95
95
|
}
|
|
96
|
-
}
|
|
96
|
+
})
|
|
97
97
|
}
|