Crash with reanimated layout(entering, exiting animations)
What happened?
We have a persistent crash when we're using entering/exiting animations with layout reanimated. Tested with react-navigation and crash was not detected
Code which affecting - Block.tsx -> Animated.View
entering={FadeIn.delay(FADE_IN_DURATION)}
exiting={FadeOut.delay(FADE_IN_DURATION)}
From xcode we've received different errors but the one of them was :
*** Assertion failure in -[RCTComponentViewRegistry componentViewDescriptorWithTag:](), /Users/user/AwesomeProject/node_modules/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.mm:76
ReanimatedError: Exception in HostFunction: <unknown>, js engine: reanimated
https://github.com/user-attachments/assets/db4e8e9a-c9e4-4781-966d-7e80278a056c
What was the expected behaviour?
app doesn't crash persistently
Was it tested on latest react-native-navigation?
- [x] I have tested this issue on the latest react-native-navigation release and it still reproduces.
Help us reproduce this issue!
I have an reproducable repo https://github.com/Belobopka/wix-rnn-rnlayout-crash2
In what environment did this happen?
React Native Navigation version: 8.3.0 React Native version: 0.77.2 Has Fabric (React Native's new rendering system) enabled: (yes/no) yes Node version: v18.20.8 Device model: iphone 15 pro iOS version: 18.1
~~I've noticed that when we push component(Main) and go back(to App) in the example - RCTSurfaceHostingView dealloc is called and it removes RootView(tag 11). And after that components losing their rootview and crash occures. I'm not sure if this is correct behavior, because without using the entering exiting animation the root view(RCTSurfaceHostingView) persists between screen navigation~~
UPD: Not actual, event without entering/exiting animations dealloc of RCTSurfaceHostingView was fired But what i found - parentTag for components hadn't been updated when RootComponentView had changed from tag 11 to 21 - this means that parent tag doesn't update correctly for component when navigation with exiting animation
~~Futher investigation - I noticed that some nodes don't unmount when needed and what i found -
reanimated has LayoutAnimationsProxy::endLayoutAnimation with param shouldRemove. When we return {}; instead of~~
if (!shouldRemove || !nodeForTag_.contains(tag)) {
return {};
}
~~it won't crash and nodes with old root view removed correctly after the Main(second screen) was unmounted.
It seems like the main reason is LayoutAnimationsProxy::endLayoutAnimation~~
auto node = nodeForTag_[tag];
auto mutationNode = std::static_pointer_cast<MutationNode>(node);
mutationNode->state = DEAD;
deadNodes.insert(mutationNode);
Which with wix/rnn breaks the "exiting" animations. And it seems like LayoutAnimationsProxy::handleRemovals doing something that doesn't remove nodes correctly.
UPD -
if (isRNSScreen(node)) {
isScreenPop = true;
}
This seems to be the main reason, rns(react native screens) check doesn't work for our case. I think for wix/rnn we need to add check mutation.oldChildShadowView.componentName = RNNScreen||RNNScreenStack.
UPD 2: just for testing I've added a custom component wrap with specific componentName=ViewTest, then added this name to the isRNSScreen check, wrapped all my screens in this custom view and all is working!
Thanks for reporting this. We're doing our RN 0.77 new arch upgrade and had a couple crashes. It seems like the crashes were resolved after removing all exiting animations. No issues with entering animations.
We're using react-native-reanimated version 3.18.0 as that's the highest version supporting RN 0.77.
It seems that react native screens library had the same problem - https://github.com/software-mansion/react-native-screens/issues/2545
I tested patching reanimated with the solution from the react-native-screens issue above, but it didn't help with the crashing
True, because wix/react-native-navigation doesn't wrap screen components with a custom view as react-native-screens did. To fix this problem we need to add a custom component wrapper(empty View will work). Then we need to wrap all our screens in react code with our custom view. And then we need to add the custom view name to the isRNSScreen check in reanimated. It's working but only in this case with reanimated exiting animations. For modals from this issue it won't help https://github.com/wix/react-native-navigation/issues/8083
https://github.com/software-mansion/react-native-reanimated/issues/8344
with the new 3.18.2 the crash is gone but I still notice missing elements with.
https://github.com/user-attachments/assets/c4ed9b89-d000-4991-ac67-39f0418831ba
entering={FadeIn.delay(FADE_IN_DURATION)}
exiting={FadeOut.delay(FADE_IN_DURATION)}
Please try to upgrade to RN 78 and reanimated 4.x. Released 8.5.0-snapshot.2034 supports also RN 79
Thanks I'll try 079 + 4.x Because I've tried rn 78 with rnn 4.1.6 and the problem persists
@Belobopka it's a great feedback for the reanimated guys. Can you please attach your reproduction to the my ticket? I'm afraid that the new version will not help. Anyway, I'm releasing the official version with support for 0.79. Hopefully support for 0.80-0.83 will be also very soon
https://github.com/wix/react-native-navigation/releases/tag/8.6.0
@gosha212 Thanks, I've written to the reanimated ticked.
@Belobopka Thanks for your help to make this project better!