[Web LA] Fix interaction with react-freeze
#7114
Open
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.
Summary
Preface
This issue was reported in Expensify.
In order for
exiting
animation to work, we have to prolong component's life. We do this by creating a copy of it and then assigning animation to the clone. The problem is that we cannot simply useelement.cloneNode(true)
as cloning children this way would create a copy, therefore if they also haveexiting
animation it would be assigned into original children. Here we have two issues:Problem 1. is solved by adding
Second one was solved by using the following loop:
appendChild
moves
node into another place in the tree without making a copy. This approach made nestedexiting
animations easier.react-freeze
There's a catch. With
react-freeze
, component is not unmounted from HTML tree - it just becomes invisible. When weunfreeze
component, it goes back to being visible, but if it hadexiting
animation, its children were moved into its cloned. Therefore, if anything (for exampleReact
) would try to modify subtree of given node, it would throw error (for example using methods likeinsertBefore
orremoveChild
Solution
To make
exiting
work withreact-freeze
, we add logic that once more performs reparenting, moving children again to its original parent after animation finishes (or gets cancelled).If
freeze
was not used, then these children will be unmounted anyway, but iffreeze
was used,React
can now properly interact with children.Other possibilities
We also tried one more solution - clone children and place them in the original parent. However, it still throws errors. My guess is that either
cloneNode
doesn't create exact copy (using===
operator yieldsfalse
) or there are more conditions that have to be met when using methods likeinsertBefore
.Test plan
Tested on the following code: