Skip to content

Fix differ creating or deleting a view that a nested (un)flattening moves - #58648

Open
pawicao wants to merge 2 commits into
react:mainfrom
pawicao:@pawicao/fix-differ-zindex-nested-flatten
Open

pawicao wants to merge 2 commits into
react:mainfrom
pawicao:@pawicao/fix-differ-zindex-nested-flatten

Conversation

@pawicao

@pawicao pawicao commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #58647

Summary:

When a view flattens in the same commit in which its parent unflattens, and one of its children has a negative zIndex, the differ creates that child again while it's still mounted, or deletes it even though it only moves.

On iOS this crashes in RCTComponentViewRegistry (Debug) or with a SIGSEGV in RCTMountingManager (Release). The zIndex sorts the child before the view that contains it, and the nested recursion then matches it through a different ShadowViewNodePair, so inOtherTree() stayed false on the candidate.

I made the final create/delete loop in calculateShadowViewMutationsFlattener also skip candidates whose tag the recursion recorded in the sub-visited map. I also fixed unvisitedRecursiveChildPairs storing a pointer to a loop-local copy.

Changelog:

[GENERAL] [FIXED] - Fix the differ creating a mounted view again, or deleting a moved view, when a child with a negative zIndex moves in a nested flatten/unflatten

Test Plan:

The reproducer from #58647 no longer crashes on iOS with React Native built from source with this change; without it, it crashes on the first swap.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 23, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Sep 23, 2026
@javache

javache commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Please add a test which covers this scenario.

@pawicao

pawicao commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

@javache thanks, I added the test

pawicao and others added 2 commits September 23, 2026 15:39
…oves

When a view flattens in the same commit in which its parent unflattens,
a child with a negative zIndex is sorted before the view that contains it.
The final loop of calculateShadowViewMutationsFlattener then took it for
a new or removed view, because the nested recursion matched it through a
different ShadowViewNodePair. Skip candidates the recursion recorded in
the sub-visited map.

Also stop keeping a pointer to a loop-local copy in
unvisitedRecursiveChildPairs.

Fixes react#58647

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pawicao
pawicao force-pushed the @pawicao/fix-differ-zindex-nested-flatten branch from b41cf31 to d4b9539 Compare September 23, 2026 13:40

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fabric][iOS] Differ creates a mounted view again when a child with negative zIndex moves in a nested flatten/unflatten

2 participants