Skip to content

Commit fb1089b

Browse files
authored
Fix updating SharedValue crash (#4315)
## Description #4158 added [`useJSResponderHandler`](https://github.com/software-mansion/react-native-gesture-handler/blob/main/packages/react-native-gesture-handler/src/v3/hooks/useJSResponderHandler.ts). The problem here is that `notifyEnabledChanged` is initialized as `runOnJS`, and then passed to UI. `runOnJS` should be executed on UI, otherwise app throws error: ``` Error: [Worklets] Tried to synchronously call a Remote Function. Called "anonymous" on the UI Runtime. 222-E/ReactNativeJS(28820): See https://docs.swmansion.com/react-native-worklets/docs/guides/troubleshooting#tried-to-synchronously-call-a-remote-function for more details. ``` ## Test plan <details> <summary>Tested on the following example:</summary> ```tsx import React, { useState } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { GestureDetector, Touchable, usePanGesture, } from 'react-native-gesture-handler'; import Animated, { useSharedValue } from 'react-native-reanimated'; export const COLORS = { offWhite: '#f8f9ff', headerSeparator: '#eef0ff', PURPLE: '#b58df1', DARK_PURPLE: '#7d63d9', NAVY: '#001A72', RED: '#A41623', YELLOW: '#F2AF29', GREEN: '#0F956F', DARK_GREEN: '#217838', GRAY: '#ADB1C2', KINDA_RED: '#FFB2AD', DARK_SALMON: '#d97973', KINDA_YELLOW: '#FFF096', KINDA_GREEN: '#C4E7DB', KINDA_BLUE: '#A0D5EF', LIGHT_BLUE: '#5f97c8', WEB_BLUE: '#1067c4', ANDROID: '#34a853', }; export default function SharedValueEnabledExample() { const enabled = useSharedValue(true); const [enabledLabel, setEnabledLabel] = useState(true); const pan = usePanGesture({ enabled }); return ( <View style={styles.container}> <Touchable onPress={() => { enabled.value = !enabled.value; setEnabledLabel(!enabledLabel); }} style={{ padding: 16, backgroundColor: COLORS.WEB_BLUE, borderRadius: 8, }} /> <Text style={styles.status}>{`enabled: ${enabledLabel}`}</Text> <GestureDetector gesture={pan}> <Animated.View style={[styles.box]} /> </GestureDetector> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', paddingTop: 24, }, status: { fontSize: 18, marginVertical: 16, }, box: { width: 160, height: 160, borderRadius: 16, backgroundColor: COLORS.PURPLE, }, }); ``` </details>
1 parent 98cb1e7 commit fb1089b

2 files changed

Lines changed: 9 additions & 5 deletions

File tree

packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ let Reanimated:
7676
handlers: (((event: T) => void) | null)[]
7777
): (event: T) => void;
7878
// TODO: runOnJS and runOnUI are deprecated. These should be removed in near future.
79-
runOnJS<A extends unknown[], R>(
79+
runOnJS: <A extends unknown[], R>(
8080
fn: (...args: A) => R
81-
): (...args: Parameters<typeof fn>) => void;
81+
) => (...args: Parameters<typeof fn>) => void;
8282
runOnUI<A extends any[], R>(
8383
fn: (...args: A) => R
8484
): (...args: Parameters<typeof fn>) => void;

packages/react-native-gesture-handler/src/v3/hooks/useJSResponderHandler.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,20 @@ export function useJSResponderHandler<
6363
return;
6464
}
6565

66-
const notifyEnabledChanged = reanimated.runOnJS(() => {
66+
const { runOnJS } = reanimated;
67+
68+
const notifyEnabledChanged = () => {
6769
setEnabledSharedValueRevision((revision) => revision + 1);
68-
});
70+
};
6971

7072
const attachListeners = (
7173
sharedValues: SharedValue<boolean>[],
7274
id: number,
73-
listener: () => void
75+
notify: () => void
7476
) => {
7577
'worklet';
78+
const listener = runOnJS(notify);
79+
7680
for (const sharedValue of sharedValues) {
7781
sharedValue.addListener(id, listener);
7882
}

0 commit comments

Comments
 (0)