Repository navigation
Commit 70f655a
authored
Only keep a cloned node's layout when its children's layout results match
Summary:
When a host node is cloned with its children passed in (`passChildrenWhenCloningPersistedNodes`), `YogaLayoutableShadowNode::updateYogaChildren` keeps the clone's layout clean if every new child is clean and styled like the child it replaces. That misses children that are clean and styled the same but carry a different layout. Yoga then reuses the parent's cached layout, never visits those children, and they keep their stale layout.
Runtime shadow node reference updates produce exactly such children when `<Activity>` hides a subtree:
1. The renderer commits a `display: none` clone H of the hidden subtree's host root V. H gets its own runtime reference; the renderer keeps V, which still holds the layout and layout cache from when it was visible.
2. Laying out H zeroes out clones of V's children. Those clones inherit the children's runtime references, so the renderer now holds the zeroed revisions of V's children while it still holds the non-zeroed V.
3. Any re-render inside the subtree clones those zeroed children and then V with the new children. Every check passes, so V's clone keeps V's cached layout.
4. When the subtree is revealed, Yoga reuses that cache and the content stays at 0x0.
With the children appended one by one instead, the append always dirties the parent, so this only shows up with the flag on.
Also require each new child's layout results (`yoga::LayoutResults`: computed layout and layout cache) to match those of the child it replaces before keeping the clone clean. A parent's cached layout is only valid for the layouts its children had when it was computed. A child cloned without layout changes copies its layout results, so the common case keeps the clone clean.
`configVersion` is left out of the comparison: every clone gets its own Yoga config, and `Node::setConfig()` re-aligns the layout's `configVersion` with it. Comparing it would, for example, dirty a `display: none` parent's ancestors on every commit that clones it, which `YogaDirtyFlagTest.dirtyChildOfHiddenNodeMustNotDirtyIt` guards against.
Changelog: [General][Fixed] - Fix content laid out at zero size after revealing an `<Activity>` subtree when children are passed into clones
Reviewed By: javache
Differential Revision: D131502045
Pull Request resolved: #599841 parent ad2e8f2 commit 70f655a
3 files changed
Lines changed: 82 additions & 3 deletions
File tree
- packages/react-native/ReactCommon/react/renderer
- components/view
- tests
- core/__docs__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
347 | 347 | | |
348 | 348 | | |
349 | 349 | | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
350 | 361 | | |
351 | 362 | | |
352 | 363 | | |
| |||
386 | 397 | | |
387 | 398 | | |
388 | 399 | | |
| 400 | + | |
| 401 | + | |
389 | 402 | | |
390 | | - | |
| 403 | + | |
| 404 | + | |
391 | 405 | | |
392 | 406 | | |
393 | 407 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
559 | 559 | | |
560 | 560 | | |
561 | 561 | | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
562 | 615 | | |
563 | 616 | | |
564 | 617 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
52 | | - | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
0 commit comments