-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError: Attempting to define property on object that is not extensible #2426
Comments
Issue validatorThe issue is valid! |
So the problem is in gesture handler: const gestureHandler = useAnimatedGestureHandler<
PanGestureHandlerGestureEvent,
{ startX: number; startY: number }
>({
onStart: (_, context) => {
context.startX = translateX.value;
},
onActive: (event, context) => {
translateX.value = context.startX + event.translationX;
},
onEnd: ({ translationX }) => {
if (Math.abs(translationX) < labelOpacityInterpolation[1]) {
translateX.value = withSpring(0);
translateY.value = withSpring(0);
return;
}
applyAction(
translationX > 0 ? SwipeAction.Like : SwipeAction.Dislike,
true,
);
},
}); If I comment applyAction call it starts working. |
This bug can be avoided by this hack: // 1. create wrapper over onSwiped
const onSwipedImpl = (action: SwipeAction, triggerCallback: boolean) => {
onSwiped(item, action, triggerCallback);
};
const applyAction = (action: SwipeAction, triggerCallback = true) => {
'worklet';
translateX.value = withTiming(
getAnimationEndX(action, windowWidth),
DEFAULT_ANIMATION_CONFIG,
);
translateY.value = withTiming(
getAnimationEndY(action, windowHeight),
action === SwipeAction.SuperLike
? { duration: 700 }
: DEFAULT_ANIMATION_CONFIG,
);
// 2. call onSwipedImpl here
runOnJS(onSwipedImpl)(action, triggerCallback);
}; |
Could you show your implementation of |
@gentlee import React from 'react';
import { View, Button } from 'react-native';
import Animated, { useAnimatedGestureHandler } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';
function Component() {
const testObject = {
a: 1
};
const gestureHandler = useAnimatedGestureHandler({
onStart: () => {
'worklet'
console.log("is UI:", _WORKLET)
testObject.a = 2;
}
});
const changeValue = () => {
testObject.a = 2;
};
return (
<View>
<PanGestureHandler onGestureEvent={gestureHandler}>
<Animated.View
style={{ width: 200, height: 80, backgroundColor: 'black', margin: 30 }}
/>
</PanGestureHandler>
<Button title="click" onPress={() => changeValue()} />
</View>
);
}
export default Component;
I think that exactly happens in your case. Especially if you pass Let me know if you have more questions. |
But how do we solve this? |
@galgord It depends on your specific case. But generally, you need to avoid passing objects directly to the worklet if you want to modify them from other threads. Only SharedValue (useSharedValue) can be modified from any thread. My example with working setter: import React from 'react';
import { View, Button } from 'react-native';
import Animated, { useAnimatedGestureHandler, runOnJS } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';
function Component() {
const testObject = {
a: 1
};
const setter = (value) => {
testObject.a = value;
}
const gestureHandler = useAnimatedGestureHandler({
onStart: () => {
'worklet'
console.log("is UI:", _WORKLET)
runOnJS(setter)(2);
}
});
const changeValue = () => {
testObject.a = 2;
};
return (
<View>
<PanGestureHandler onGestureEvent={gestureHandler}>
<Animated.View
style={{ width: 200, height: 80, backgroundColor: 'black', margin: 30 }}
/>
</PanGestureHandler>
<Button title="click" onPress={() => changeValue()} />
</View>
);
}
export default Component; Is it the answer to your question? |
@piaskowyk so to avoid this problem we need to create function that captures as much state that we need as possible, and capture this function from the worklet? May be this note should be added to worklet documentation? Because i've spent a lot of time to fix that and docs didn't help me. |
Worked for me thanks! |
Description
Got red error screen in iOS:
Expected behavior
No errors or better description.
Actual behavior & steps to reproduce
On app launch.
Snack or minimal code example
Probably problem is in one of these worklets:
All there worklets are called from both JS and UI threads.
Package versions
Affected platforms
The text was updated successfully, but these errors were encountered: