Add unflattenedParentTag to remove mutations#44043
Add unflattenedParentTag to remove mutations#44043bartlomiejbloniarz wants to merge 3 commits intofacebook:mainfrom
Conversation
Base commit: a6a7cdf |
|
@dmytrorykun has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
|
Hey, thanks for the PR. Have you considered any other options other than adding this to remove mutation? If so, how does this solution stack up against them? This information is something that can be detected from mount instructions, why not do that? If we decide to add something like this to the differentiator, it will be hard to remove it in the future. It would be great to evaluate other options before adding something to the differentiator. |
|
Hi @sammy-SC, The other approach that I considered, would be to obtain this structure in the commit hook. I would have to calculate mutations using the differentiator, traverse the ShadowTree, looking for deleted views and then store the information about their parents. I think it wouldn't be optimal to calculate mutations twice for every commit (in the commit hook, and then in the Mounting Coordinator). There could also be some issues if there was a commit hook running after our hook. I think adding this logic to the Differentiator is better, because all the necessary data is there, so there is no need for additional computation of mutations and shadowTree traversal. I'm not sure how this could be detected from mount instructions? If I understand correctly CREATE and INSERT mutations only operate on the flattened view hierarchy, so this unflattend structure wouldn't be available there. Or do you mean something different by mount instructions? |
## Summary This PR brings layout animations to the New Architecture. In the Old Architecture layout animations were implemented separately for iOS and Android. The new implementation leverages the `MountingOverrideDelegate` to intercept and animate layout changes right before they are sent to the platform. This way we can have a unified implementation across platforms (it should also work beyond Android and iOS). ## `MountingOverrideDelegate` The override delegate is called every time a new transaction is about to be mounted. It gives us full access to the mutations list and allows us to change them. This mechanism is used by RN, also in Layout Animations. It is important to note that this way we never commit a new `ShadowTree` - we only change the mutations that are sent to the platform. This means that those changes don't influence the layout of other views, which is consistent with the Old Arch implementation. ## Limitations - configuration of entering animations is done using `nativeID` since I was unable to obtain the `tag` of a view before the animation should start - `skipExiting` does not work properly on android (I'm not sure why the `componentWillUnmount` method is called there earlier than on iOS) - `globalOriginX` and `globalOriginY` currently return the values of `originX` and `originY` - this part will probably require a native `convertPoint` function to be used - due to view flattening some exiting animations behave differently. The issue is explained in [this PR](facebook/react-native#44043). ## Test plan Go through the Layout Animations examples in the FabricExample app.
|
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
|
This PR was closed because it has been stalled for 7 days with no activity. |
1 similar comment
|
This PR was closed because it has been stalled for 7 days with no activity. |
## Summary This PR brings layout animations to the New Architecture. In the Old Architecture layout animations were implemented separately for iOS and Android. The new implementation leverages the `MountingOverrideDelegate` to intercept and animate layout changes right before they are sent to the platform. This way we can have a unified implementation across platforms (it should also work beyond Android and iOS). ## `MountingOverrideDelegate` The override delegate is called every time a new transaction is about to be mounted. It gives us full access to the mutations list and allows us to change them. This mechanism is used by RN, also in Layout Animations. It is important to note that this way we never commit a new `ShadowTree` - we only change the mutations that are sent to the platform. This means that those changes don't influence the layout of other views, which is consistent with the Old Arch implementation. ## Limitations - configuration of entering animations is done using `nativeID` since I was unable to obtain the `tag` of a view before the animation should start - `skipExiting` does not work properly on android (I'm not sure why the `componentWillUnmount` method is called there earlier than on iOS) - `globalOriginX` and `globalOriginY` currently return the values of `originX` and `originY` - this part will probably require a native `convertPoint` function to be used - due to view flattening some exiting animations behave differently. The issue is explained in [this PR](facebook/react-native#44043). ## Test plan Go through the Layout Animations examples in the FabricExample app.
Summary:
I am currently implementing Layout Animations for the new architecture in reanimated. One of the issues that I encountered is that view flattening changes the child-parent relationship when views don't form a stacking context. In the current implementation we relay heavily on this relationship in order to prevent parent components from being removed until the child exiting animation ends. To make this work on the new architecture we would have to encourage users to use
collapasable: falseon non-Animatedparent components (or make those componentsAnimated), which could lead to unnecessarily deep trees being created. That's why in this PR I added theunflattenedParentTagproperty toRemovemutations. This way the unflattened parent-child relationship can be obtained in theMountingOverrideDelegate- which is where Layout Animations are implemented.Changelog:
[GENERAL] [ADDED] -
unflattenedParentTaginShadowViewNodePairandShadowViewMutation(only for Remove mutations)[GENERAL] [CHANGED] -
sliceChildShadowNodeViewPairsRecursivelyV2to store theunflattenedParentTaginShadowViewNodePairs, so that they can be easily obtained when calculating mutations.Test Plan:
I used the following example to test the logic in RNTester:
The example looks like this:

In the debug navigator we can see that red components are actually siblings of the blue component (and also that the layout-only views are not included in the host tree)

But in the remove mutations that were generated when the blue component was removed, we can see that the

unflattenedParentTagallows us to see that those red components should be treated as children of the blue component: