virtual-scroller 1.15.2 → 1.15.3

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.
@@ -19,7 +19,7 @@ import createScrollableContainerResizeHelpers from './VirtualScroller.onContaine
19
19
  import createItemsHelpers from './VirtualScroller.items.js'
20
20
 
21
21
  /**
22
- * @param {function} getItemsContainerElement — Returns the container DOM `Element`.
22
+ * @param {function} getItemsContainerElement — Returns the container DOM `Element` (or `null`).
23
23
  * @param {any[]} items — The list of items.
24
24
  * @param {Object} [options] — See README.md.
25
25
  * @return {VirtualScroller}
@@ -76,18 +76,31 @@ export default function VirtualScrollerConstructor(
76
76
  getScrollableContainer = () => scrollableContainer
77
77
  }
78
78
 
79
- // Sometimes, when `new VirtualScroller()` instance is created,
80
- // `getItemsContainerElement()` might not be ready to return the "container" DOM Element yet
81
- // (for example, because it's not rendered yet). That's the reason why it's a getter function.
82
- // For example, in React `<VirtualScroller/>` component, a `VirtualScroller`
79
+ // Sometimes, when `new VirtualScroller()` "core" instance is created,
80
+ // `getItemsContainerElement()` function might not yet be ready to return the "container" DOM Element.
81
+ // For example, because the "container" DOM Element not rendered yet.
82
+ // That's the reason why it's a getter function rather than a simple variable.
83
+ //
84
+ // As an example, in React `<VirtualScroller/>` component, a "core" `VirtualScroller`
83
85
  // instance is created in the React component's `constructor()`, and at that time
84
- // the container Element is not yet available. The container Element is available
85
- // in `componentDidMount()`, but `componentDidMount()` is not executed on server,
86
- // which would mean that React `<VirtualScroller/>` wouldn't render at all
87
- // on server side, while with the `getItemsContainerElement()` approach, on server side,
88
- // it still "renders" a list with a predefined amount of items in it by default.
89
- // (`initiallyRenderedItemsCount`, or `1`).
90
- this.getItemsContainerElement = getItemsContainerElement
86
+ // the "container" DOM Element has not been rendered yet.
87
+ // The "container" DOM Element is only guaranteed to have been rendered
88
+ // by the time `useEffect()` callback function is called, but at the same time `useEffect()`
89
+ // is only executed on client side and is not executed on server side at all.
90
+ // Still, the code has to work both in a web browser and on the server during the initial
91
+ // "server-side render", i.e. it still must render the list during the initial
92
+ // "server-side render". So `VirtualScroller` can't simply be skipped during server-side render.
93
+ // It has to render something, and that something has to be correct.
94
+ // This means that the "core" `VirtualScroller` should at least correctly compute the state
95
+ // regardless of whether the `itemsContainerElement` exists or not.
96
+ //
97
+ this.getItemsContainerElement = () => {
98
+ const element = getItemsContainerElement()
99
+ if (element === null) {
100
+ throw new Error('[virtual-scroller] Items container element is `null`')
101
+ }
102
+ return element
103
+ }
91
104
 
92
105
  // if (prerenderMargin === undefined) {
93
106
  // // Renders items which are outside of the screen by this "prerender margin".
@@ -212,16 +225,6 @@ function createHelpers({
212
225
  this.getItemsContainerElement
213
226
  )
214
227
 
215
- // If the items "container" element is mounted at this stage,
216
- // remove any accidental text nodes from it (like whitespace).
217
- //
218
- // Also, this guards against cases when someone accidentally tries
219
- // using `VirtualScroller` on a non-empty element.
220
- //
221
- if (this.getItemsContainerElement()) {
222
- this.itemsContainer.clear()
223
- }
224
-
225
228
  this.isItemsContainerElementTableBody = () => {
226
229
  return this.engine === DOMEngine &&
227
230
  this.getItemsContainerElement().tagName === 'TBODY'
@@ -54,6 +54,11 @@ export default function() {
54
54
  const getItemId = this._getItemId
55
55
  if (getItemId) {
56
56
  const itemId = getItemId(item)
57
+ // Performance notes:
58
+ // Doing an `.findIndex()` operation on a very large array could be inefficient
59
+ // because it would have to check every element of the array.
60
+ // In case of any hypothetical performance-related issues,
61
+ // the code could use a `new Map()` as an "index" for finding individual items by ID.
57
62
  const i = items.findIndex((item) => getItemId(item) === itemId)
58
63
  if (i >= 0) {
59
64
  return i
@@ -43,9 +43,18 @@ export default class VirtualScroller {
43
43
  if (!isRestart) {
44
44
  this.setUpState()
45
45
  this.waitingForRender = true
46
+
46
47
  // If `render()` function parameter was passed,
47
48
  // perform an initial render.
48
49
  if (this._render) {
50
+ // Remove any accidental text nodes (like whitespace) from the items container.
51
+ //
52
+ // This also guards against the cases when someone accidentally tries to create
53
+ // a `VirtualScroller` in a non-empty items container element.
54
+ //
55
+ this.itemsContainer.clear()
56
+
57
+ // Perform the initial render of the list.
49
58
  this._render(this.getState())
50
59
  }
51
60
  }
@@ -98,8 +98,8 @@ export default function useVirtualScroller({
98
98
  // `getItemsContainerElement()` function is called both before it has mounted
99
99
  // and after it has mounted. Only validate the ref's value after it has mounted.
100
100
  //
101
- if (hasMounted.current) {
102
- if (!itemsContainerRef.current) {
101
+ if (!itemsContainerRef.current) {
102
+ if (hasMounted.current) {
103
103
  throw new Error('[virtual-scroller] Did you forget to pass the returned `itemsContainerRef` property as the items container component\'s `ref`?')
104
104
  }
105
105
  }