software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
9.05k stars 1.31k forks source link

[SET] App freeze due to infinite loop when running transition multiple times #6324

Open fredrifoUni opened 3 months ago

fredrifoUni commented 3 months ago

Description

There is an issue where getSharedElementForCurrentTransition can get stuck in an infinite while loop if the transition has been run before. For me it was consistently happening when performing the same transition twice

We created a hacky patch that fixes the crashing issue:

diff --git a/node_modules/react-native-reanimated/apple/LayoutReanimation/REASharedTransitionManager.m b/node_modules/react-native-reanimated/apple/LayoutReanimation/REASharedTransitionManager.m
index 4cc7d02..41a3e6d 100644
--- a/node_modules/react-native-reanimated/apple/LayoutReanimation/REASharedTransitionManager.m
+++ b/node_modules/react-native-reanimated/apple/LayoutReanimation/REASharedTransitionManager.m
@@ -249,11 +249,18 @@ static BOOL _isConfigured = NO;
     // find sibling for shared view
     NSNumber *siblingViewTag = _findPrecedingViewTagForTransition(sharedView.reactTag);
     REAUIView *siblingView = nil;
+      
+    // Check if sibling view tag isn't updating
+    int *prevSiblingViewTag = nil;
     do {
       siblingView = [_animationManager viewForTag:siblingViewTag];
       if (siblingView == nil) {
         [self clearAllSharedConfigsForViewTag:siblingViewTag];
+        prevSiblingViewTag = siblingViewTag.intValue;
         siblingViewTag = _findPrecedingViewTagForTransition(sharedView.reactTag);
+        if(prevSiblingViewTag == siblingViewTag.intValue){
+          break;
+        }
       }
     } while (siblingView == nil && siblingViewTag != nil);

Steps to reproduce

I have not had time to verify this in a new repo, but here are the steps I went through.

  1. Create a Native Stack Navigator
  2. Navigate to new screen while passing the sharedElementTag navigation.navigate("MainScreen", { screen: "ScreenName", params: { data, sharedTransitionTag } })
  3. The animation works.
  4. Go back to MainScreen
  5. Trigger the same navigation with the unchanged sharedTransitionTag
  6. APP FREEZE

Snack or a link to a repository

https://snack.expo.io/

Reanimated version

3.13.0

React Native version

0.73.6

Platforms

iOS

JavaScript runtime

Hermes

Workflow

None

Architecture

Paper (Old Architecture)

Build type

Debug app & production bundle

Device

Real device

Device model

No response

Acknowledgements

Yes

github-actions[bot] commented 3 months ago

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

DavitVosk commented 1 month ago

Any update here please? I have the same problem

draggie commented 1 week ago

Proposed solution by @fredrifoUni seems to work, maybe it could be applied ?