diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp index e257f39e079c..c0640e89de47 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -77,6 +77,7 @@ ShadowNode::ShadowNode( react_native_assert(children_); traits_.set(ShadowNodeTraits::Trait::ChildrenAreShared); + traits_.set(fragment.traits.get()); for (const auto& child : *children_) { child->family_->setParent(family_); @@ -107,6 +108,7 @@ ShadowNode::ShadowNode( react_native_assert(children_); traits_.set(ShadowNodeTraits::Trait::ChildrenAreShared); + traits_.set(fragment.traits.get()); if (fragment.children) { for (const auto& child : *children_) { @@ -128,11 +130,10 @@ ShadowNode::Unshared ShadowNode::clone( propsParserContext, props_, RawProps(*family.nativeProps_DEPRECATED)); auto clonedNode = componentDescriptor.cloneShadowNode( *this, - { - props, - fragment.children, - fragment.state, - }); + {.props = props, + .children = fragment.children, + .state = fragment.state, + .traits = fragment.traits}); return clonedNode; } else { // TODO: We might need to merge fragment.priops with @@ -330,10 +331,8 @@ ShadowNode::Unshared ShadowNode::cloneTree( ShadowNode::sameFamily(*children.at(childIndex), *childNode)); children[childIndex] = childNode; - childNode = parentNode.clone({ - ShadowNodeFragment::propsPlaceholder(), - std::make_shared(children), - }); + childNode = parentNode.clone( + {.children = std::make_shared(children)}); } return std::const_pointer_cast(childNode); diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.h b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.h index 66ea8cdc0d52..a521feac02a4 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.h @@ -26,6 +26,7 @@ struct ShadowNodeFragment { const Props::Shared& props = propsPlaceholder(); const ShadowNode::SharedListOfShared& children = childrenPlaceholder(); const State::Shared& state = statePlaceholder(); + const ShadowNodeTraits traits = {}; /* * Placeholders. diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h index c8cb72f5e5b2..ab1386e3c463 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h @@ -70,6 +70,7 @@ class ShadowNodeTraits { // to be cloned before the first mutation. ChildrenAreShared = 1 << 8, + Reserved = 1 << 31, }; /* 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 ac00541f1030..cc67c4a16746 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/ShadowNodeTest.cpp @@ -212,6 +212,21 @@ TEST_F(ShadowNodeTest, handleCloneFunction) { EXPECT_EQ(nodeAB_->getProps(), nodeABClone->getProps()); } +TEST_F(ShadowNodeTest, handleCloningWithTraits) { + auto clonedWithoutTraits = nodeAB_->clone({}); + + EXPECT_FALSE(clonedWithoutTraits->getTraits().check( + ShadowNodeTraits::Trait::Reserved)); + + auto newTraits = ShadowNodeTraits(); + newTraits.set(ShadowNodeTraits::Trait::Reserved); + + auto clonedWithTraits = clonedWithoutTraits->clone({.traits = newTraits}); + + EXPECT_TRUE( + clonedWithTraits->getTraits().check(ShadowNodeTraits::Trait::Reserved)); +} + TEST_F(ShadowNodeTest, handleState) { auto family = componentDescriptor_.createFamily(ShadowNodeFamilyFragment{ /* .tag = */ 9,