Skip to content

Commit 976c849

Browse files
Bartlomiej Bloniarzmeta-codesync[bot]
authored andcommitted
Calll the ShadowNode::cloneMultiple callback for each cloned node (#54431)
Summary: Pull Request resolved: #54431 The original intention by the cloneMultiple method was to give the possibility of defining the cloning method only for the nodes definied by the list of families. But this way it is impossible to for example set the value of `runtimeShadowNodeReference` in the fragment, so instead we now pass the responsibility of cloning to the user for all the cloned nodes. # Changelog [General] [Changed] - cloneMultiple now invokes the callback for every cloned node, instead of doing that only for the nodes in `familiesToUpdate` Reviewed By: javache Differential Revision: D85852143 fbshipit-source-id: 9cf0540f546f5f070a918b8a4434ad40f78d91f6
1 parent 6ddba30 commit 976c849

2 files changed

Lines changed: 36 additions & 10 deletions

File tree

packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,6 @@ namespace {
412412

413413
std::shared_ptr<ShadowNode> cloneMultipleRecursive(
414414
const ShadowNode& shadowNode,
415-
const std::unordered_set<const ShadowNodeFamily*>& familiesToUpdate,
416415
const std::unordered_map<const ShadowNodeFamily*, int>& childrenCount,
417416
const std::function<std::shared_ptr<
418417
ShadowNode>(const ShadowNode&, const ShadowNodeFragment&)>& callback) {
@@ -430,16 +429,12 @@ std::shared_ptr<ShadowNode> cloneMultipleRecursive(
430429
std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>(
431430
children);
432431
}
433-
(*newChildren)[i] = cloneMultipleRecursive(
434-
*children[i], familiesToUpdate, childrenCount, callback);
432+
(*newChildren)[i] =
433+
cloneMultipleRecursive(*children[i], childrenCount, callback);
435434
}
436435
}
437436

438-
ShadowNodeFragment fragment{.children = newChildren};
439-
if (familiesToUpdate.contains(family)) {
440-
return callback(shadowNode, fragment);
441-
}
442-
return shadowNode.clone(fragment);
437+
return callback(shadowNode, {.children = newChildren});
443438
}
444439

445440
} // namespace
@@ -479,8 +474,7 @@ std::shared_ptr<ShadowNode> ShadowNode::cloneMultiple(
479474
return nullptr;
480475
}
481476

482-
return cloneMultipleRecursive(
483-
*this, familiesToUpdate, childrenCount, callback);
477+
return cloneMultipleRecursive(*this, childrenCount, callback);
484478
}
485479

486480
#pragma mark - DebugStringConvertible

packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,35 @@ TEST_F(ShadowNodeTest, cloneMultiple) {
342342
EXPECT_EQ(newNodeABA->getTag(), nodeABA_->getTag());
343343
EXPECT_EQ(newNodeABA.get(), nodeABA_.get());
344344
}
345+
346+
TEST_F(ShadowNodeTest, cloneMultipleWithSingleFamily) {
347+
auto newProps = std::make_shared<const TestProps>();
348+
auto newRoot = nodeA_->cloneMultiple(
349+
{&nodeAB_->getFamily()},
350+
[&](const ShadowNode& oldShadowNode, const ShadowNodeFragment& fragment) {
351+
return oldShadowNode.clone({
352+
.props = newProps,
353+
.children = fragment.children,
354+
.state = fragment.state,
355+
});
356+
});
357+
358+
EXPECT_EQ(newRoot->getTag(), nodeA_->getTag());
359+
// The callback is called for each cloned node, so the root props are also
360+
// updated
361+
EXPECT_EQ(newRoot->getProps(), newProps);
362+
363+
auto newNodeAA = newRoot->getChildren()[0];
364+
EXPECT_EQ(newNodeAA->getTag(), nodeAA_->getTag());
365+
EXPECT_EQ(newNodeAA->getProps(), nodeAA_->getProps());
366+
// AA was cloned when its parent was cloned as it was shared
367+
EXPECT_NE(newNodeAA.get(), nodeAA_.get());
368+
369+
auto newNodeAB = newRoot->getChildren()[1];
370+
EXPECT_EQ(newNodeAB->getTag(), nodeAB_->getTag());
371+
EXPECT_EQ(newNodeAB->getProps(), newProps);
372+
373+
auto newNodeABA = newNodeAB->getChildren()[0];
374+
EXPECT_EQ(newNodeABA->getTag(), nodeABA_->getTag());
375+
EXPECT_EQ(newNodeABA.get(), nodeABA_.get());
376+
}

0 commit comments

Comments
 (0)