Skip to content

Commit 4ab7d53

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
fix a crash in view culling when the differentiator produces create instruction for existing tag (facebook#50843)
Summary: Pull Request resolved: facebook#50843 changelog: [internal] Fix a crash where view culling produces a mutation to create a view that was already created. Without the change in Differentiator.cpp, the test fails assert on [StubViewTree.cpp:69](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/mounting/stubs/StubViewTree.cpp#L69). Reviewed By: rubennorte Differential Revision: D72818343 fbshipit-source-id: 8aec3ccf967f453c619a9495dcd32b43b21afea3
1 parent 90a93aa commit 4ab7d53

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,3 +1162,80 @@ test('scroll view parent is unflattened and view becomes culled', () => {
11621162
'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}',
11631163
]);
11641164
});
1165+
1166+
test('parent-child flattening with culling', () => {
1167+
const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100});
1168+
1169+
Fantom.runTask(() => {
1170+
root.render(
1171+
<ScrollView
1172+
style={{height: 100, width: 100}}
1173+
contentOffset={{x: 0, y: 60}}>
1174+
<View
1175+
style={{
1176+
marginTop: 100,
1177+
opacity: 0,
1178+
}}>
1179+
<View
1180+
style={{
1181+
marginTop: 50,
1182+
opacity: 0,
1183+
}}>
1184+
<View
1185+
nativeID={'child'}
1186+
style={{height: 10, width: 10, backgroundColor: 'red'}}
1187+
/>
1188+
</View>
1189+
</View>
1190+
</ScrollView>,
1191+
);
1192+
});
1193+
1194+
expect(root.takeMountingManagerLogs()).toEqual([
1195+
'Update {type: "RootView", nativeID: (root)}',
1196+
'Create {type: "ScrollView", nativeID: (N/A)}',
1197+
'Create {type: "View", nativeID: (N/A)}',
1198+
'Create {type: "View", nativeID: (N/A)}',
1199+
'Create {type: "View", nativeID: (N/A)}',
1200+
'Create {type: "View", nativeID: "child"}',
1201+
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}',
1202+
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}',
1203+
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}',
1204+
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}',
1205+
'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}',
1206+
]);
1207+
1208+
// force parent-child to be flattened.
1209+
Fantom.runTask(() => {
1210+
root.render(
1211+
<ScrollView
1212+
style={{height: 100, width: 100}}
1213+
contentOffset={{x: 0, y: 60}}>
1214+
<View
1215+
style={{
1216+
marginTop: 100,
1217+
}}>
1218+
<View
1219+
style={{
1220+
marginTop: 50,
1221+
}}>
1222+
<View
1223+
nativeID={'child'}
1224+
style={{height: 10, width: 10, backgroundColor: 'red'}}
1225+
/>
1226+
</View>
1227+
</View>
1228+
</ScrollView>,
1229+
);
1230+
});
1231+
1232+
expect(root.takeMountingManagerLogs()).toEqual([
1233+
'Update {type: "View", nativeID: "child"}',
1234+
'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}',
1235+
'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}',
1236+
'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}',
1237+
'Delete {type: "View", nativeID: (N/A)}',
1238+
'Delete {type: "View", nativeID: (N/A)}',
1239+
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}',
1240+
]);
1241+
});

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,6 @@ static void calculateShadowViewMutationsFlattener(
663663
// Case 1: child mode is the same as parent.
664664
// This is a flatten-flatten, or unflatten-unflatten.
665665
if (childReparentMode == reparentMode) {
666-
// TODO(T217775046): Find a test case for this branch of view
667-
// flattening + culling.
668666
calculateShadowViewMutationsFlattener(
669667
scope,
670668
childReparentMode,
@@ -679,8 +677,8 @@ static void calculateShadowViewMutationsFlattener(
679677
: parentTag),
680678
subVisitedNewMap,
681679
subVisitedOldMap,
682-
adjustedOldCullingContext,
683-
adjustedNewCullingContext);
680+
oldCullingContext,
681+
newCullingContext);
684682
} else {
685683
// Get flattened nodes from either new or old tree
686684
// TODO(T217775046): Find a test case for this branch of view

0 commit comments

Comments
 (0)