Skip to content

Conversation

@tomekzaw
Copy link
Member

@tomekzaw tomekzaw commented Oct 27, 2025

Summary

Fixes #8422.

Co-authored-with: Bartłomiej Błoniarz [email protected]

Test plan

Copy link
Contributor

@RodolfoSilva RodolfoSilva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ssukru
Copy link

ssukru commented Oct 27, 2025

Ekran Resmi 2025-10-27 14 14 03

i think this is wrong, no?

@tomekzaw
Copy link
Member Author

@ssukru Yes, my mistake, fixed in 04980dd, thanks!

@floydkim
Copy link

floydkim commented Nov 5, 2025

Thank you. After modifying the library according to this PR, my crash issue has been resolved.
I hope it can be released soon.

react-native-reanimated+4.1.3.patch

patch

diff --git a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
index 05acd4f..fa0832c 100644
--- a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
+++ b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
@@ -598,7 +598,7 @@ bool ReanimatedModuleProxy::handleRawEvent(
   // (res == true), but for now handleEvent always returns false. Thankfully,
   // performOperations does not trigger a lot of code if there is nothing to
   // be done so this is fine for now.
-  performOperations();
+  performOperations(true);
   return res;
 }
 
@@ -649,15 +649,15 @@ double ReanimatedModuleProxy::getCssTimestamp() {
   return currentCssTimestamp_;
 }
 
-void ReanimatedModuleProxy::performOperations() {
+void ReanimatedModuleProxy::performOperations(const bool isTriggeredByEvent) {
   ReanimatedSystraceSection s("ReanimatedModuleProxy::performOperations");
 
-  auto flushRequestsCopy = std::move(layoutAnimationFlushRequests_);
-  for (const auto surfaceId : flushRequestsCopy) {
-    uiManager_->getShadowTreeRegistry().visit(
-        surfaceId, [](const ShadowTree &shadowTree) {
-          shadowTree.notifyDelegatesOfUpdates();
-        });
+  if (!isTriggeredByEvent) {
+    auto flushRequestsCopy = std::move(layoutAnimationFlushRequests_);
+    for (const auto surfaceId : flushRequestsCopy) {
+      uiManager_->getShadowTreeRegistry().visit(
+          surfaceId, [](const ShadowTree &shadowTree) { shadowTree.notifyDelegatesOfUpdates(); });
+    }
   }
 
   jsi::Runtime &rt =
diff --git a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h
index 9e0599a..ac089c0 100644
--- a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h
+++ b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h
@@ -117,7 +117,7 @@ class ReanimatedModuleProxy
   void maybeRunCSSLoop();
   double getCssTimestamp();
 
-  void performOperations();
+  void performOperations(const bool isTriggeredByEvent);
 
   void setViewStyle(
       jsi::Runtime &rt,
diff --git a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp
index 01247a9..0bb5c80 100644
--- a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp
+++ b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp
@@ -127,8 +127,8 @@ bool NativeProxy::isAnyHandlerWaitingForEvent(
       eventName, emitterReactTag);
 }
 
-void NativeProxy::performOperations() {
-  reanimatedModuleProxy_->performOperations();
+void NativeProxy::performOperations(const bool isTriggeredByEvent) {
+  reanimatedModuleProxy_->performOperations(isTriggeredByEvent);
 }
 
 bool NativeProxy::getIsReducedMotion() {
diff --git a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h
index 8a811e5..2945299 100644
--- a/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h
+++ b/node_modules/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h
@@ -62,7 +62,7 @@ class NativeProxy : public jni::HybridClass<NativeProxy>,
   bool isAnyHandlerWaitingForEvent(
       const std::string &eventName,
       const int emitterReactTag);
-  void performOperations();
+  void performOperations(const bool isTriggeredByEvent);
   bool getIsReducedMotion();
   void requestRender(std::function<void(double)> onRender);
   void registerEventHandler();
diff --git a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.java b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.java
index a02506c..b82043d 100644
--- a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.java
+++ b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.java
@@ -110,7 +110,7 @@ public class NativeProxy {
 
   public native boolean isAnyHandlerWaitingForEvent(String eventName, int emitterReactTag);
 
-  public native void performOperations();
+  public native void performOperations(boolean isTriggeredByEvent);
 
   protected native void installJSIBindings();
 
@@ -488,7 +488,7 @@ public class NativeProxy {
   void maybeFlushUIUpdatesQueue() {
     UiThreadUtil.assertOnUiThread();
     if (!mNodesManager.isAnimationRunning()) {
-      mNodesManager.performOperations();
+      mNodesManager.performOperations(false);
     }
   }
 }
diff --git a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java
index a322746..52def06 100644
--- a/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java
+++ b/node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java
@@ -115,10 +115,10 @@ public class NodesManager implements EventDispatcherListener {
     }
   }
 
-  public void performOperations() {
+  public void performOperations(boolean isTriggeredByEvent) {
     UiThreadUtil.assertOnUiThread();
     if (mNativeProxy != null) {
-      mNativeProxy.performOperations();
+      mNativeProxy.performOperations(isTriggeredByEvent);
     }
   }
 
@@ -155,7 +155,7 @@ public class NodesManager implements EventDispatcherListener {
           }
         }
 
-        performOperations();
+        performOperations(false);
       }
 
       mCallbackPosted.set(false);
@@ -189,7 +189,7 @@ public class NodesManager implements EventDispatcherListener {
       // the UI thread.
       if (UiThreadUtil.isOnUiThread()) {
         handleEvent(event);
-        performOperations();
+        performOperations(true);
       } else {
         String eventName = mCustomEventNamesResolver.resolveCustomEventName(event.getEventName());
         int viewTag = event.getViewTag();
diff --git a/node_modules/react-native-reanimated/apple/reanimated/apple/native/NativeProxy.mm b/node_modules/react-native-reanimated/apple/reanimated/apple/native/NativeProxy.mm
index 793d28d..19a4e2d 100644
--- a/node_modules/react-native-reanimated/apple/reanimated/apple/native/NativeProxy.mm
+++ b/node_modules/react-native-reanimated/apple/reanimated/apple/native/NativeProxy.mm
@@ -46,7 +46,7 @@ - (void *)runtime;
   std::weak_ptr<ReanimatedModuleProxy> weakReanimatedModuleProxy = reanimatedModuleProxy; // to avoid retain cycle
   [nodesManager registerPerformOperations:^() {
     if (auto reanimatedModuleProxy = weakReanimatedModuleProxy.lock()) {
-      reanimatedModuleProxy->performOperations();
+      reanimatedModuleProxy->performOperations(false);
     }
   }];
 

@tomekzaw tomekzaw added this pull request to the merge queue Nov 7, 2025
Merged via the queue into main with commit fc062e3 Nov 7, 2025
18 checks passed
@tomekzaw tomekzaw deleted the @tomekzaw/perform-operations-for-events branch November 7, 2025 13:47
@Brma1048
Copy link

@tomekzaw Thanks for the fix, when will this fix be released?

@tomekzaw
Copy link
Member Author

tomekzaw commented Nov 10, 2025

It's gonna be released in 4.2.0.

@Brma1048
Copy link

Do you think its safe to use the 4.2.0 nightly build? Or should we wait for the official release?

@tomekzaw
Copy link
Member Author

It should be safe to use 4.2.0-nightly as long as you make sure that your app works correctly after the bump.

@rpyoyo
Copy link

rpyoyo commented Nov 12, 2025

It's gonna be released in 4.2.0.

When is version 4.2.0 coming out?

@Brma1048
Copy link

@tomekzaw we still got these crashes with the nightly build 4.2.0-nightly-20251109-b10bd9cb3

@Brma1048
Copy link

Here is the sentry crash https://chrono24-gmbh.sentry.io/share/issue/ee6a62892aac4dec989d5bb17e9d29c0/

@floelm
Copy link

floelm commented Nov 12, 2025

We are also using a patch with the changeset of this MR and seeing the exact same error in prod as @Brma1048

Can't really give any other details unfortunately

@floydkim
Copy link

floydkim commented Nov 13, 2025

In my case, some issues were resolved.
However, the same problem related to react-navigation screen transitions is still exsists.
(I'm currently using version 4.1.3 with the changes from this PR patched in.)

This PR fixed the crash that occurred when closing a modal implemented with reanimated while simultaneously popping a screen.
(Native error log: RNGestureHandlerRootView contains null child at index 7 when traversal in dispatchGetDisplayList, the view may have been removed.)

I haven't yet found the minimal conditions to reproduce the remaining issue, but it seemed to crash when the navigation state changed rapidly in a short moment.

Edit:
I am using @react-navigation/native-stack and @react-navigation/native.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

9 participants