Fix error when dynamically removing views#281
Merged
lucdion merged 4 commits intolayoutBox:masterfrom Dec 20, 2025
Merged
Conversation
heoblitz
commented
Oct 16, 2025
| rootFlexContainer.flex.markDirty() | ||
| rootFlexContainer.flex.layout() | ||
|
|
||
| XCTAssertTrue(rootFlexContainer.subviews.isEmpty) |
Collaborator
Author
There was a problem hiding this comment.
Calling markDirty() on rootFlexContainer is unnecessary, but it's an area where users can easily make mistakes.
In the code before this PR, it bypasses the early return condition and causes an error.
| YGNodeMarkDirty(node); | ||
| if (YGNodeHasMeasureFunc(node)) { | ||
| YGNodeMarkDirty(node); | ||
| } |
Collaborator
Author
There was a problem hiding this comment.
I considered modifying the isLeaf logic in YGLayout, but decided not to proceed because there are separate properties being used, making it difficult to guarantee the existing logic.
Therefore, add defensive logic for the assertFatal conditions inside Yoga.
Collaborator
Author
There was a problem hiding this comment.
void Node::setMeasureFunc(YGMeasureFunc measureFunc) {
if (measureFunc == nullptr) {
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
// places in Litho
setNodeType(NodeType::Default);
} else {
yoga::assertFatalWithNode(
this,
children_.empty(),
"Cannot set measure function: Nodes with measure functions cannot have "
"children.");
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
// places in Litho
setNodeType(NodeType::Text);
}
measureFunc_ = measureFunc;
}void YGNodeMarkDirty(const YGNodeRef nodeRef) {
const auto node = resolveRef(nodeRef);
yoga::assertFatalWithNode(
node,
node->hasMeasureFunc(),
"Only leaf nodes with custom measure functions "
"should manually mark themselves as dirty");
node->markDirtyAndPropagate();
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR?
Currently, FlexLayout does not guarantee that the UIView hierarchy state matches the Yoga node structure. This is because nodes are only updated during the layout process by following the UIView hierarchy.
When a child UIView is dynamically removed and markDirty() is called, it causes an error and terminates the program because it doesn't align with Yoga's logic.
In React Native's case, views that become leaves are fixed and used consistently, but FlexLayout allows any UIView to become a leaf. Therefore, we add defensive code to prevent logical errors.
Impact on Existing Users
Without this defensive code, errors were already being triggered by Yoga. In all other cases, the behavior remains identical to the previous version.
close #280