I am trying to change state from a pan gesture (React Native Gesture Handler).
const [localShowRecents, setLocalShowRecents] = useState(false)
const translateY = useSharedValue(0);
const gesture = Gesture.Pan()
.onStart(() => {
context.value = { y: translateY.value }
})
.onUpdate((event) => {
//console.log(event.translationY);
translateY.value = event.translationY context.value.y;
translateY.value = Math.max(translateY.value, MAX_TRANSLATE_Y)
})
.onEnd(() => {
if (translateY.value > -SCREEN_HEIGHT / 32){
setLocalShowRecents(true); //change state
}
}
When I try to update state from the ".onEnd()" function, I get the error "Tried to synchronously call function from a different thread." How do I properly change state from the gesture handler?
CodePudding user response:
Your Reanimated components work on the device's UI thread. The rest of your code will work on the device's JS thread. The way your code is written, it tries to call a Javascript function on the UI thread, which causes the error you're seeing.
This is why Reanimated includes the runOnJS
method. Instead of
setLocalShowRecents(true)
you can use
runOnJS(setLocalShowRecents)(true);
Note the modified call signature - runOnJS(fn)(args)
. You can read more about runOnJS here in the Reanimated docs.