diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp index 7b894673cdbf..f8383851616e 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -412,7 +412,6 @@ namespace { std::shared_ptr cloneMultipleRecursive( const ShadowNode& shadowNode, - const std::unordered_set& familiesToUpdate, const std::unordered_map& childrenCount, const std::function(const ShadowNode&, const ShadowNodeFragment&)>& callback) { @@ -430,16 +429,12 @@ std::shared_ptr cloneMultipleRecursive( std::make_shared>>( children); } - (*newChildren)[i] = cloneMultipleRecursive( - *children[i], familiesToUpdate, childrenCount, callback); + (*newChildren)[i] = + cloneMultipleRecursive(*children[i], childrenCount, callback); } } - ShadowNodeFragment fragment{.children = newChildren}; - if (familiesToUpdate.contains(family)) { - return callback(shadowNode, fragment); - } - return shadowNode.clone(fragment); + return callback(shadowNode, {.children = newChildren}); } } // namespace @@ -479,8 +474,7 @@ std::shared_ptr ShadowNode::cloneMultiple( return nullptr; } - return cloneMultipleRecursive( - *this, familiesToUpdate, childrenCount, callback); + return cloneMultipleRecursive(*this, childrenCount, callback); } #pragma mark - DebugStringConvertible diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp b/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp index a6ea8da1d62f..2ac02a75c3e2 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp @@ -342,3 +342,35 @@ TEST_F(ShadowNodeTest, cloneMultiple) { EXPECT_EQ(newNodeABA->getTag(), nodeABA_->getTag()); EXPECT_EQ(newNodeABA.get(), nodeABA_.get()); } + +TEST_F(ShadowNodeTest, cloneMultipleWithSingleFamily) { + auto newProps = std::make_shared(); + auto newRoot = nodeA_->cloneMultiple( + {&nodeAB_->getFamily()}, + [&](const ShadowNode& oldShadowNode, const ShadowNodeFragment& fragment) { + return oldShadowNode.clone({ + .props = newProps, + .children = fragment.children, + .state = fragment.state, + }); + }); + + EXPECT_EQ(newRoot->getTag(), nodeA_->getTag()); + // The callback is called for each cloned node, so the root props are also + // updated + EXPECT_EQ(newRoot->getProps(), newProps); + + auto newNodeAA = newRoot->getChildren()[0]; + EXPECT_EQ(newNodeAA->getTag(), nodeAA_->getTag()); + EXPECT_EQ(newNodeAA->getProps(), nodeAA_->getProps()); + // AA was cloned when its parent was cloned as it was shared + EXPECT_NE(newNodeAA.get(), nodeAA_.get()); + + auto newNodeAB = newRoot->getChildren()[1]; + EXPECT_EQ(newNodeAB->getTag(), nodeAB_->getTag()); + EXPECT_EQ(newNodeAB->getProps(), newProps); + + auto newNodeABA = newNodeAB->getChildren()[0]; + EXPECT_EQ(newNodeABA->getTag(), nodeABA_->getTag()); + EXPECT_EQ(newNodeABA.get(), nodeABA_.get()); +}