You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fixed (iOS) Relayout not Working for Nested Inline (#41352)
Summary:
React Native, the text inline is made versatile by design. Being managed in an alien layout logic (i.e., text paragraph), inline views work seamlessly as if in normal **flex** layout. The capacities such as animation and relayout, however, requires extra efforts on native layer.
This PR fixed one critical issue for inline, i.e., `setState()` is not working when inline contains nested views.
Closes#41348
Demo (Fixed)
https://github.com/facebook/react-native/assets/149237137/2b42d657-4024-476b-bf0c-be25ef4f8c0c
## Problem in technical:
This issue is caused by a bug in `RCTShadowView::sizeThatFitsMinimumSize()` which accidentally unlink children (of yoga nodes) with their parent (owner). More specifically, on the critical path, it
1. first **shallow** clones the current node
```
YGNodeRef clonedYogaNode = YGNodeClone(self.yogaNode);
```
2. then calls `YGNodeCalculateLayout()` using the cloned node
3. deallocate the cloned node `YGNodeFree()`
One unseen implication of `YGNodeFree()` is to unlink all its children (because of the **shallow** clone)
```
for (size_t i = 0; i < childCount; i++) {
auto child = node->getChild(i);
child->setOwner(nullptr);
}
```
Next, let's examine,
**How nullptr of owner can cause the broken `setState()` of nested inline views**
The orphan children has two consequences:
**a**. the changes on child node (`setState()`) cannot be propagated to the parent (`YGNodeMarkDirty` -> `node->markDirtyAndPropagate();`);
**b**. `YGNodeCalculateLayout()` (`yoga::calculateLayoutImpl`) will create new children instances when orphan is detected (see below)
```
node->cloneChildrenIfNeeded(); // line 1599 # CalculateLayout.cpp
```
Both compounded are contributing the failed `setState()`. Respectively,
**a** causes early return of `YGNodeCalculateLayout()` because parent is recognized as not *dirty*;
**b** clones a new *dirty* node which replaces the child which is supposed to be *cleaned* within `YGNodeCalculateLayout()`. And this is the *dirty* node detected by the assertion mentioned in the issue description #41348.
## The fix:
The fix introduced in this PR is to relink the children with their parent in `RCTShadowView::sizeThatFitsMinimumSize()`
## Changelog:
[IOS] [FIXED] - `setState` is not working for nested inline views in text
Pull Request resolved: #41352
Test Plan:
Test directly in rn-tester
TBD
Reviewed By: yungsters
Differential Revision: D51071338
Pulled By: NickGerleman
fbshipit-source-id: 1f3d8a3e1e03cb11577f903e43f2c2cce9e07b6e
0 commit comments