diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp index aa511645bbf0..bf2b90809078 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp @@ -210,7 +210,8 @@ static void sliceChildShadowNodeViewPairsRecursively( size_t& startOfStaticIndex, ViewNodePairScope& scope, Point layoutOffset, - const ShadowNode& shadowNode) { + const ShadowNode& shadowNode, + Tag unflattenedParentTag) { for (const auto& sharedChildShadowNode : shadowNode.getChildren()) { auto& childShadowNode = *sharedChildShadowNode; @@ -254,12 +255,16 @@ static void sliceChildShadowNodeViewPairsRecursively( if (areChildrenFlattened) { storedOrigin = origin; } + if (shadowNode.getTraits().check(ShadowNodeTraits::Trait::FormsView)){ + unflattenedParentTag = shadowNode.getTag(); + } scope.push_back( {shadowView, &childShadowNode, areChildrenFlattened, isConcreteView, - storedOrigin}); + storedOrigin, + unflattenedParentTag}); if (shadowView.layoutMetrics.positionType == PositionType::Static) { auto it = pairList.begin(); @@ -268,14 +273,14 @@ static void sliceChildShadowNodeViewPairsRecursively( startOfStaticIndex++; if (areChildrenFlattened) { sliceChildShadowNodeViewPairsRecursively( - pairList, startOfStaticIndex, scope, origin, childShadowNode); + pairList, startOfStaticIndex, scope, origin, childShadowNode, unflattenedParentTag); } } else { pairList.push_back(&scope.back()); if (areChildrenFlattened) { size_t pairListSize = pairList.size(); sliceChildShadowNodeViewPairsRecursively( - pairList, pairListSize, scope, origin, childShadowNode); + pairList, pairListSize, scope, origin, childShadowNode, unflattenedParentTag); } } } @@ -296,7 +301,7 @@ ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairs( size_t startOfStaticIndex = 0; sliceChildShadowNodeViewPairsRecursively( - pairList, startOfStaticIndex, scope, layoutOffset, shadowNode); + pairList, startOfStaticIndex, scope, layoutOffset, shadowNode, shadowNode.getTag()); // Sorting pairs based on `orderIndex` if needed. reorderInPlaceIfNeeded(pairList); @@ -558,7 +563,8 @@ static void updateMatchedPair( ShadowViewMutation::RemoveMutation( parentShadowView, oldPair.shadowView, - static_cast(oldPair.mountIndex))); + static_cast(oldPair.mountIndex), + oldPair.unflattenedParentTag)); } mutationContainer.deleteMutations.push_back( ShadowViewMutation::DeleteMutation(oldPair.shadowView)); @@ -571,7 +577,8 @@ static void updateMatchedPair( ShadowViewMutation::RemoveMutation( parentShadowView, newPair.shadowView, - static_cast(oldPair.mountIndex))); + static_cast(oldPair.mountIndex), + newPair.unflattenedParentTag)); } // Even if node's children are flattened, it might still be a @@ -775,13 +782,15 @@ static void calculateShadowViewMutationsFlattener( ShadowViewMutation::RemoveMutation( node.shadowView, treeChildPair.otherTreePair->shadowView, - static_cast(treeChildPair.mountIndex))); + static_cast(treeChildPair.mountIndex), + treeChildPair.otherTreePair->unflattenedParentTag)); } else { mutationContainer.removeMutations.push_back( ShadowViewMutation::RemoveMutation( node.shadowView, treeChildPair.shadowView, - static_cast(treeChildPair.mountIndex))); + static_cast(treeChildPair.mountIndex), + treeChildPair.unflattenedParentTag)); } } else { // treeChildParent represents the "new" version of the node, so @@ -1201,6 +1210,7 @@ static void calculateShadowViewMutations( parentShadowView, oldChildPair.shadowView, static_cast(oldChildPair.mountIndex), + oldChildPair.unflattenedParentTag, isRecursionRedundant || ShadowViewMutation:: PlatformSupportsRemoveDeleteTreeInstruction)); @@ -1399,7 +1409,8 @@ static void calculateShadowViewMutations( ShadowViewMutation::RemoveMutation( parentShadowView, otherTreeView, - static_cast(oldChildPair.mountIndex))); + static_cast(oldChildPair.mountIndex), + oldChildPair.unflattenedParentTag)); continue; } @@ -1407,7 +1418,8 @@ static void calculateShadowViewMutations( ShadowViewMutation::RemoveMutation( parentShadowView, oldChildPair.shadowView, - static_cast(oldChildPair.mountIndex))); + static_cast(oldChildPair.mountIndex), + oldChildPair.unflattenedParentTag)); deletionCandidatePairs.insert( {oldChildPair.shadowView.tag, &oldChildPair}); diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowView.h b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowView.h index 6c776f31bab1..a234a14098da 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowView.h +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowView.h @@ -79,6 +79,7 @@ struct ShadowViewNodePair final { */ bool isConcreteView{true}; Point contextOrigin{0, 0}; + Tag unflattenedParentTag{-1}; size_t mountIndex{0}; diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.cpp index 25445b1badc6..7d41e508eb8d 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.cpp @@ -57,6 +57,7 @@ ShadowViewMutation ShadowViewMutation::RemoveMutation( ShadowView parentShadowView, ShadowView childShadowView, int index, + Tag unflattenedParentTag, bool isRedundantOperation) { return { /* .type = */ Remove, @@ -65,6 +66,7 @@ ShadowViewMutation ShadowViewMutation::RemoveMutation( /* .newChildShadowView = */ {}, /* .index = */ index, /* .isRedundantOperation */ isRedundantOperation, + /* .parentTag */ unflattenedParentTag }; } @@ -116,12 +118,14 @@ ShadowViewMutation::ShadowViewMutation( ShadowView oldChildShadowView, ShadowView newChildShadowView, int index, - bool isRedundantOperation) + bool isRedundantOperation, + Tag unflattenedParentTag) : type(type), parentShadowView(std::move(parentShadowView)), oldChildShadowView(std::move(oldChildShadowView)), newChildShadowView(std::move(newChildShadowView)), index(index), + unflattenedParentTag(unflattenedParentTag), isRedundantOperation(isRedundantOperation) {} #if RN_DEBUG_STRING_CONVERTIBLE diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.h b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.h index de399dfe1c6a..fda5a11d6b5b 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.h +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.h @@ -57,6 +57,7 @@ struct ShadowViewMutation final { ShadowView parentShadowView, ShadowView childShadowView, int index, + Tag unflattenedParentTag = -1, bool isRedundantOperation = false); /* @@ -96,6 +97,7 @@ struct ShadowViewMutation final { ShadowView oldChildShadowView = {}; ShadowView newChildShadowView = {}; int index = -1; + Tag unflattenedParentTag = -1; // RemoveDeleteTree causes many Remove/Delete operations to be redundant. // However, we must internally produce all of them for any consumers that @@ -117,7 +119,8 @@ struct ShadowViewMutation final { ShadowView oldChildShadowView, ShadowView newChildShadowView, int index, - bool isRedundantOperation = false); + bool isRedundantOperation = false, + Tag unflattenedParentTag = -1); }; using ShadowViewMutationList = std::vector;