Skip to content

Commit 0ec77d8

Browse files
Bartlomiej Bloniarzfacebook-github-bot
authored andcommitted
Calll the ShadowNode::cloneMultiple callback for each cloned node (#54431)
Summary: 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
1 parent a1e534a commit 0ec77d8

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)