Fix invariant violation when nesting VirtualizedList inside ListEmptyComponent (#35875)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35875 Fixes https://github.com/facebook/react-native/issues/35871 Nested VirtualizedLists register to their parents for updates, associated to a specfific cellKey set by VirtualizedListCellContextProvider. This cellKey is usually set when rendering a cell for a data item, but we can also render a nested VirtualizedList by putting one in a ListHeaderComponent/ListFooterComponent/ListEmptyComponent. D6603342 (a010a0cebd
) added cellKeys when we render from a header/footer, but not ListEmptyComponent, so that association would silently fail earlier. D39466677 (010da67bef
) added extra invariants to child list handling, that are now triggered by this case, complaining because we are trying to unregister a child list we never successfully registered, due to a missing cellKey. This fixes the issue by providing a cellKey for ListEmptyComponent as well. Changelog: [General][Fixed] - Fix invariant violation when nesting VirtualizedList inside ListEmptyComponent Reviewed By: christophpurrer Differential Revision: D42574462 fbshipit-source-id: f76fa795bf471cb8a929c2efdbd814ea51927663
This commit is contained in:
Родитель
4cdc2c48e8
Коммит
1fef376812
|
@ -871,16 +871,19 @@ export default class VirtualizedList extends StateSafePureComponent<
|
|||
<ListEmptyComponent />
|
||||
)): any);
|
||||
cells.push(
|
||||
React.cloneElement(element, {
|
||||
key: '$empty',
|
||||
onLayout: (event: LayoutEvent) => {
|
||||
this._onLayoutEmpty(event);
|
||||
if (element.props.onLayout) {
|
||||
element.props.onLayout(event);
|
||||
}
|
||||
},
|
||||
style: StyleSheet.compose(inversionStyle, element.props.style),
|
||||
}),
|
||||
<VirtualizedListCellContextProvider
|
||||
cellKey={this._getCellKey() + '-empty'}
|
||||
key="$empty">
|
||||
{React.cloneElement(element, {
|
||||
onLayout: (event: LayoutEvent) => {
|
||||
this._onLayoutEmpty(event);
|
||||
if (element.props.onLayout) {
|
||||
element.props.onLayout(event);
|
||||
}
|
||||
},
|
||||
style: StyleSheet.compose(inversionStyle, element.props.style),
|
||||
})}
|
||||
</VirtualizedListCellContextProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,32 @@ describe('VirtualizedList', () => {
|
|||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('handles nested list in ListEmptyComponent', () => {
|
||||
const ListEmptyComponent = (
|
||||
<VirtualizedList {...baseItemProps(generateItems(1))} />
|
||||
);
|
||||
|
||||
let component;
|
||||
|
||||
ReactTestRenderer.act(() => {
|
||||
component = ReactTestRenderer.create(
|
||||
<VirtualizedList
|
||||
{...baseItemProps([])}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
ReactTestRenderer.act(() => {
|
||||
component.update(
|
||||
<VirtualizedList
|
||||
{...baseItemProps(generateItems(5))}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the viewableItems correctly in the onViewableItemsChanged callback after changing the data', () => {
|
||||
const ITEM_HEIGHT = 800;
|
||||
let data = [{key: 'i1'}, {key: 'i2'}, {key: 'i3'}];
|
||||
|
|
Загрузка…
Ссылка в новой задаче