react-native-reanimated: [Reanimated 3.3.0] runOnJs crash - "Object is not a function"

Description

I have updated my project from 2.17.0 to 3.3.0 and I am running into an issue in the following scenario:

const finishTransition = useCallback(
    (
      resolve: (value: void | PromiseLike<void>) => void,
    ) => {
       // ... some logic, not important to understand the issue
      resolve();
    },
    [onFinishedTransitioning]
  );

const handlePress = () => {
    new Promise(resolve => {
      scale.value = withSpring(2, {}, () => {
        runOnJS(finishTransition)(resolve);
      });
    }).then(() => {
      // ...
    });
  };

Calling the resolve within finishTransition using runOnJS was working fine in 2.17.0. In 3.3.0 is is throwing TypeError: Object is not a function. I had a closer look and the resolve parameter of the finishTransition function is logged as “{”__remoteFunction": {}}". There seems to be an incorrect translation happening.

Steps to reproduce

  1. Follow the description to create a code example similar to how I defined it. It seems to be related to passing a promise resolve function into the runOnJs function.

Snack or a link to a repository

https://github.com/AlexanderEggers/ReanimatedIssue

Reanimated version

3.3.0

React Native version

0.71.11

Platforms

Android, iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Paper (Old Architecture)

Build type

Debug mode

Device

Android emulator

Device model

No response

Acknowledgements

Yes

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 25 (17 by maintainers)

Commits related to this issue

Most upvoted comments

We’ll do our best to deliver it in 3.6.0. There’s still a few PRs that need to be merged prior to a release but fingers crossed it will be like next week.

@jenskuhrjorgensen actually we’re working on last fixes, fingers crossed we’ll release 3.6.0 early next week (or even today if all goes well).

@tomekzaw just tried the fix in our app and runOnJS works with function args in release mode 🍾

Thank you so much! 🙏 I’ll keep an eye on your next releases 😃

Yes, thanks. I’m already playing around with it 😀

Hi guys! @tjzel @tomekzaw We are facing an issue with RunOnJS method after your fix on v3.5.0. Specifically, we are using reanimated v3.5.2. When we pass a function (dispatch from redux v4.2.0) to RunOnJS(ourMethod)(dispatch) seems that your fix works on debug but not in production.

We captured this error log:

!object.isHostObject<ShareableJSRef>(rt) && "[Reanimated] Provided value is already an instance of ShareableJSRef." > Assertion failed: (!object.isHostObject<ShareableJSRef>(rt) && "[Reanimated] Provided value is already an instance of ShareableJSRef."), function makeShareableClone, file Shareables.cpp, line 71.
 > makeShareableClone > Shareables.cpp

Any idea of what could be the cause of this problem? Thanks!

@tomekzaw I did some more testing and I noticed that this bug is still happening in release builds. It is running fine in debug builds.

That is the patch I applied based on #4617:

diff --git a/node_modules/react-native-reanimated/src/reanimated2/shareables.ts b/node_modules/react-native-reanimated/src/reanimated2/shareables.ts
index 4f358f4..096edda 100644
--- a/node_modules/react-native-reanimated/src/reanimated2/shareables.ts
+++ b/node_modules/react-native-reanimated/src/reanimated2/shareables.ts
@@ -213,6 +213,9 @@ export function makeShareableCloneOnUIRecursive<T>(value: T): ShareableRef<T> {
   function cloneRecursive<T>(value: T): ShareableRef<T> {
     const type = typeof value;
     if ((type === 'object' || type === 'function') && value !== null) {
+      if (value.__remoteFunction) {
+        return value.__remoteFunction;
+      }
       let toAdapt: any;
       if (Array.isArray(value)) {
         toAdapt = value.map((element) => cloneRecursive(element));

@tomekzaw Thanks the fix in the PR works well for me 🙌

@tomekzaw thanks! I was facing this same issue and I can confirm, this issue is fixed in react-native-reanimated@3.6.0

@jenskuhrjorgensen FYI react-native-reanimated@3.6.0 has just been released.

@tjzel thanks for your answer! Unfortunately, it seems that our app still crashes with v3.5.4 when RunOnJS(ourMethod)(dispatch) is called, throwing the error I mentioned in my previous comment. Is there any other test or context you want us to give you to get a better idea of what could be happening with it? 😃

@tjzel promised to take a look at it soon

We’re still working on proper typing, hopefully this should make it to 3.5.0 soon.

@tomekzaw The changes work fine in debug and release builds. Thank you 😃

@AlexanderEggers I’ve pushed e76311f05c661787ffcc14bb9ab71d7403d680e7 which should fix the issue in the release mode. Could you please check if it works for you?

@AlexanderEggers thanks for letting me know, I will take a look on it.