From b64641345cc015cefda5291122196693962c7474 Mon Sep 17 00:00:00 2001 From: 5ZYSZ3K Date: Sat, 13 Jun 2026 21:43:25 +0200 Subject: [PATCH] fix: yoga crash with display:none --- .../yoga/yoga/algorithm/CalculateLayout.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 1db7a5c21af9..6e7814be2a29 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -615,9 +615,18 @@ static float computeFlexBasisForChildren( for (auto child : children) { child->processDimensions(); if (child->style().display() == Display::None) { - zeroOutLayoutRecursively(child); - child->setHasNewLayout(true); - child->setDirty(false); + // Only mutate display: none children during layout passes. Zeroing them + // out during measure-only passes contributes nothing to the measurement, + // but sets `hasNewLayout` on nodes the parent's layout pass may never + // visit (e.g. when its layout is restored from cache, skipping + // `cloneChildrenIfNeeded()`). Such a leaked flag survives the commit and + // is copied into lazily-shared clones, later tripping the ownership + // assertion in `YogaLayoutableShadowNode::layout`. + if (performLayout) { + zeroOutLayoutRecursively(child); + child->setHasNewLayout(true); + child->setDirty(false); + } continue; } if (performLayout) {