diff --git a/node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.js b/node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.js index c92ac9d..6bdc84f 100644 --- a/node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.js +++ b/node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.js @@ -47,6 +47,7 @@ import { windowSizeOrDefault, } from './VirtualizedListProps'; +import {boundRetainedRangeOnDataGrowth} from './boundRetainedRangeOnDataGrowth'; import { computeWindowedRenderLimits, keyExtractor as defaultKeyExtractor, } from './VirtualizeUtils'; @@ -706,7 +706,8 @@ class VirtualizedList extends StateSafePureComponent< // first and last could be stale (e.g. if a new, shorter items props is passed in), so we make // sure we're rendering a reasonable range here. const itemCount = newProps.getItemCount(newProps.data); - if (itemCount === prevState.renderMask.numCells()) { + const previousItemCount = prevState.renderMask.numCells(); + if (itemCount === previousItemCount) { return prevState; } @@ -741,7 +742,7 @@ class VirtualizedList extends StateSafePureComponent< } } - const constrainedCells = VirtualizedList._constrainToItemCount( + let constrainedCells = VirtualizedList._constrainToItemCount( maintainVisibleContentPositionAdjustment != null ? { first: @@ -756,6 +758,20 @@ class VirtualizedList extends StateSafePureComponent< newProps, ); + if ( + newProps.unstable_boundedRangeOnDataChange === true && + itemCount > previousItemCount + ) { + const retainedCellLimit = + maxToRenderPerBatchOrDefault(newProps.maxToRenderPerBatch) * 2; + constrainedCells = boundRetainedRangeOnDataGrowth( + constrainedCells, + previousItemCount, + itemCount, + retainedCellLimit, + ); + } + return { cellsAroundViewport: constrainedCells, renderMask: VirtualizedList._createRenderMask(newProps, constrainedCells), diff --git a/node_modules/@react-native/virtualized-lists/Lists/boundRetainedRangeOnDataGrowth.js b/node_modules/@react-native/virtualized-lists/Lists/boundRetainedRangeOnDataGrowth.js new file mode 100644 index 0000000..1e5b1f5 --- /dev/null +++ b/node_modules/@react-native/virtualized-lists/Lists/boundRetainedRangeOnDataGrowth.js @@ -0,0 +1,28 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +'use strict'; + +export function boundRetainedRangeOnDataGrowth( + cellsAroundViewport, + previousItemCount, + itemCount, + retainedCellLimit, +) { + if (itemCount <= previousItemCount) { + return cellsAroundViewport; + } + return { + first: cellsAroundViewport.first, + last: Math.min( + cellsAroundViewport.last, + cellsAroundViewport.first + retainedCellLimit - 1, + ), + }; +} diff --git a/node_modules/@react-native/virtualized-lists/Lists/VirtualizedListProps.js b/node_modules/@react-native/virtualized-lists/Lists/VirtualizedListProps.js index 9d6d49e..54324a8 100644 --- a/node_modules/@react-native/virtualized-lists/Lists/VirtualizedListProps.js +++ b/node_modules/@react-native/virtualized-lists/Lists/VirtualizedListProps.js @@ -264,8 +264,14 @@ type OptionalVirtualizedListProps = { * Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off * screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`. */ updateCellsBatchingPeriod?: ?number, + + /** + * Limits the synchronous render range retained when data grows. This is useful for lists that + * insert many bounded cells in the middle of an already-rendered range. + */ + unstable_boundedRangeOnDataChange?: ?boolean, /** * See `ViewabilityHelper` for flow type and further documentation. */ viewabilityConfig?: ViewabilityConfig,