Skip to content

Commit 4c0607e

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
add test for ViewCulling when sibling in FLatList resizes (#51311)
Summary: Pull Request resolved: #51311 changelog: [internal] add a test case for view culling to cover a crash observed in production. Reviewed By: lenaic, rubennorte Differential Revision: D74720814 fbshipit-source-id: ed1246ccbaa0d0ab51a6073f20642c1c78872f30
1 parent 7776122 commit 4c0607e

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

packages/react-native/Libraries/Components/ScrollView/__tests__/ScrollView-viewCulling-itest.js

+52-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ import type {HostInstance} from 'react-native';
1818

1919
import ensureInstance from '../../../../src/private/__tests__/utilities/ensureInstance';
2020
import * as Fantom from '@react-native/fantom';
21+
import nullthrows from 'nullthrows';
2122
import * as React from 'react';
22-
import {Modal, ScrollView, View} from 'react-native';
23+
import {FlatList, Modal, ScrollView, View} from 'react-native';
2324
import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement';
2425

2526
test('basic culling', () => {
@@ -818,6 +819,56 @@ test('culling inside of Modal', () => {
818819
]);
819820
});
820821

822+
test('nesting inside FlatList with item resizing', () => {
823+
const root = Fantom.createRoot({viewportHeight: 100, viewportWidth: 100});
824+
let _setIsExpanded = null;
825+
function ExpandableComponent() {
826+
const [isExpanded, setIsExpanded] = React.useState(false);
827+
_setIsExpanded = setIsExpanded;
828+
return <View>{isExpanded && <View style={{height: 80.5}} />}</View>;
829+
}
830+
831+
Fantom.runTask(() => {
832+
root.render(
833+
<FlatList
834+
style={{height: 100, width: 100}}
835+
data={[{key: 'one'}, {key: 'two'}]}
836+
renderItem={({item}) => {
837+
if (item.key === 'one') {
838+
return <ExpandableComponent />;
839+
} else if (item.key === 'two') {
840+
return (
841+
// position: 'absolute' is the important part that prevents Yoga from overcloning.
842+
// When Yoga overclones, differentiator visits all cloned nodes and culling is correctly
843+
// applied.
844+
<View style={{position: 'absolute'}}>
845+
<View nativeID={'parent'} style={{marginTop: 10}}>
846+
<View
847+
nativeID={'child'}
848+
style={{height: 10, width: 75, marginTop: 10}}
849+
/>
850+
</View>
851+
</View>
852+
);
853+
}
854+
}}
855+
/>,
856+
);
857+
});
858+
859+
expect(root.takeMountingManagerLogs()).toContain(
860+
'Create {type: "View", nativeID: "child"}',
861+
);
862+
863+
Fantom.runTask(() => {
864+
nullthrows(_setIsExpanded)(true);
865+
});
866+
867+
expect(root.takeMountingManagerLogs()).toContain(
868+
'Delete {type: "View", nativeID: "child"}',
869+
);
870+
});
871+
821872
describe('reparenting', () => {
822873
test('view flattening with culling', () => {
823874
const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100});

packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ static void updateMatchedPairSubtrees(
280280
return;
281281
}
282282

283-
// TODO(T217775046): find a test case for this branch.
284283
auto oldCullingContextCopy =
285284
oldCullingContext.adjustCullingContextIfNeeded(oldPair);
286285
auto newCullingContextCopy =

0 commit comments

Comments
 (0)