You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Gesture Handler跨线程报错:手势回调中如何更新状态?

在React Native Gesture Handler中正确更新组件状态

当在React Native Gesture Handler的Pan手势.onEnd()回调中直接调用React状态更新方法时,会抛出错误:Tried to synchronously call function from a different thread,原代码如下:

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
      }
})

解决方法

Gesture Handler的手势回调(比如onEnd)运行在非主线程,而React的状态更新必须在主线程执行。只需使用Reanimated提供的runOnJS函数,将状态更新方法包裹后再调用,就能确保代码在主线程执行。

修改后的代码:

import { runOnJS } from 'react-native-reanimated'; // 记得导入runOnJS

const [localShowRecents, setLocalShowRecents] = useState(false)
const translateY = useSharedValue(0);

const gesture = Gesture.Pan()
      .onStart(() => {
        context.value = { y: translateY.value }
      })
      .onUpdate((event) => {
        translateY.value = event.translationY + context.value.y;
        translateY.value = Math.max(translateY.value, MAX_TRANSLATE_Y)
      })
      .onEnd(() => {
        if (translateY.value > -SCREEN_HEIGHT / 32){
          runOnJS(setLocalShowRecents)(true); // 用runOnJS包裹状态更新方法
        }
      })

补充说明

  • runOnJS的作用是将传入的函数调度到JavaScript主线程执行,彻底避免跨线程调用的问题。
  • 请确保已经正确安装并配置了react-native-reanimated和react-native-gesture-handler,否则可能出现其他异常。

内容的提问来源于stack exchange,提问作者Ethan Stacey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:45:19