C++ state update not received when using a path-cloning commit hook #49694
Labels
Needs: Author Feedback
Needs: Version Info
p: Software Mansion
Partner: Software Mansion
Partner
Type: New Architecture
Issues and PRs related to new architecture (Fabric/Turbo Modules)
Description
This issue is related to this reanimated issue, but I think it should be solved/discussed here.
High-level overview
The issue is that if we have a commit hook, that clones some nodes in the
ShadowTree
, applied on a commit that changes the c++ state of aShadowNode
, then this c++ state update will get lost.More detailed description
The best way to describe this issue is to show an example. Let's say we have the following tree:
Let's say there is a state update, that changes state from 0 to 1. Before the commit hook is called we have (ViewWithState and Parent got cloned):
Now let's say our commit hook want's to do some work on
SomeView
. Then it has to clone it (alsoParent
has to be cloned, as we don't really know in the commit hook if theParent
can be modified in place). This is what it should look like:But actually what happens is this:
This is because when we clone the
Parent
, this line is hit, causingadoptYogaChild
(here) to be called for every child. InadoptYogaChild
there is a check that determines whether we have to clone the given child. ForCustomComponentWithState
it decides that it has to be cloned (even though it has never been commited to any revision). The clone call there passes emptyShadowNodeFragment
causing the default value to be used, which issourceShadowNode.getMostRecentState()
- so the last mounted state. That's why the new state gets lost.Repro explanation
I created a repro for iOS on a separate branch in rn-tester. The repro doesn't include reanimated, I just added a simple commit hook, and modified a bit the sample custom component to showcase the lost state update.
I use the
changeColor
function to trigger a state update. In the logs you can see how the state update is triggered, commit hook is called and an unsealedSampleNativeComponentShadowNode
gets cloned, but no state update is received on the native side.If we change the
clone
call inadoptYogaChild
, to use the source node state, the state update will come.I don't think that's a proper solution, because I think we shouldn't be cloning this node altogether as it is not sealed, but I don't fully understand the connection between
yogaNodes
andShadowNodes
, so I don't know what the fix here would be.Steps to reproduce
React Native Version
main
Affected Platforms
The reproduction is for iOS, but this is mostly related to the
ShadowTree
state update pipeline, so should be applicable to any platform.Areas
Fabric - The New Renderer
Reproducer
https://github.com/bartlomiejbloniarz/react-native/tree/%40bartlomiejbloniarz/commit-hook-repro
Screenshots and Videos
No response
The text was updated successfully, but these errors were encountered: