diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp index 99e5798206c..44b0f8f468f 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -107,6 +107,9 @@ ShadowNode::ShadowNode( react_native_assert(props_); react_native_assert(children_); + // State could have been progressed above by checking + // `sourceShadowNode.getMostRecentState()`. + traits_.unset(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate); traits_.set(ShadowNodeTraits::Trait::ChildrenAreShared); traits_.set(fragment.traits.get()); diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h index ab1386e3c46..325321e5b90 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h @@ -70,7 +70,8 @@ class ShadowNodeTraits { // to be cloned before the first mutation. ChildrenAreShared = 1 << 8, - Reserved = 1 << 31, + // Indicates that the node was cloned because of native state update. + ClonedByNativeStateUpdate = 1 << 9, }; /* 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 b8811813db4..44411abc24f 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp @@ -216,15 +216,20 @@ TEST_F(ShadowNodeTest, handleCloningWithTraits) { auto clonedWithoutTraits = nodeAB_->clone({}); EXPECT_FALSE(clonedWithoutTraits->getTraits().check( - ShadowNodeTraits::Trait::Reserved)); + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); auto newTraits = ShadowNodeTraits(); - newTraits.set(ShadowNodeTraits::Trait::Reserved); + newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate); auto clonedWithTraits = clonedWithoutTraits->clone({.traits = newTraits}); - EXPECT_TRUE( - clonedWithTraits->getTraits().check(ShadowNodeTraits::Trait::Reserved)); + EXPECT_TRUE(clonedWithTraits->getTraits().check( + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); + + auto clonedAgain = clonedWithTraits->clone({}); + + EXPECT_FALSE(clonedAgain->getTraits().check( + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); } TEST_F(ShadowNodeTest, handleState) { @@ -285,7 +290,7 @@ TEST_F(ShadowNodeTest, handleState) { TEST_F(ShadowNodeTest, testCloneTree) { auto& family = nodeABA_->getFamily(); auto newTraits = ShadowNodeTraits(); - newTraits.set(ShadowNodeTraits::Trait::Reserved); + newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate); auto rootNode = nodeA_->cloneTree( family, [newTraits](ShadowNode const& oldShadowNode) { @@ -293,21 +298,22 @@ TEST_F(ShadowNodeTest, testCloneTree) { }, newTraits); - EXPECT_TRUE(rootNode->getTraits().check(ShadowNodeTraits::Trait::Reserved)); + EXPECT_TRUE(rootNode->getTraits().check( + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); EXPECT_FALSE(rootNode->getChildren()[0]->getTraits().check( - ShadowNodeTraits::Trait::Reserved)); + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); auto const& firstLevelChild = *rootNode->getChildren()[1]; - EXPECT_TRUE( - firstLevelChild.getTraits().check(ShadowNodeTraits::Trait::Reserved)); + EXPECT_TRUE(firstLevelChild.getTraits().check( + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); EXPECT_FALSE(firstLevelChild.getChildren()[1]->getTraits().check( - ShadowNodeTraits::Trait::Reserved)); + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); auto const& secondLevelchild = *firstLevelChild.getChildren()[0]; - EXPECT_TRUE( - secondLevelchild.getTraits().check(ShadowNodeTraits::Trait::Reserved)); + EXPECT_TRUE(secondLevelchild.getTraits().check( + ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)); }