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

在Gesture Detector中调用函数时应用崩溃,求排查方案

解决Gesture Detector中调用函数导致应用崩溃的问题

问题根源

你遇到的崩溃核心原因是:

  • 父组件传入的rollDown是普通JavaScript函数,并非Reanimated的worklet函数,不能直接在手势回调(属于UI线程worklet)中调用。
  • 你尝试的两种方式都存在错误:
    1. 把callRollDown定义为worklet后调用rollDown,相当于在UI线程执行了JS线程的函数,导致线程上下文不匹配。
    2. 使用runOnJS(callRollDown)()是错误用法,runOnJS应该直接包裹需要在JS线程执行的普通函数,而非worklet。

修正方案

直接在手势的onEnd回调中,用runOnJS包裹父组件传入的rollDown函数调用,不需要额外定义worklet版本的callRollDown:

const SortingModal = React.forwardRef(({rollDown}, ref) => {
  const {height: MAX_MODAL_HEIGHT} = Dimensions.get('screen');
  const translateY = useSharedValue(0);
  const context = useSharedValue({y: 0});

  const gesture = Gesture.Pan()
    .onStart(() => {
      context.value = { y: translateY.value };
    })
    .onUpdate((event) => {
      if (event.translationY < MAX_MODAL_HEIGHT) {
        translateY.value = event.translationY + context.value.y;
        translateY.value = Math.max(translateY.value, -MAX_MODAL_HEIGHT);
      }
    })
    .onEnd(() => {
      if (translateY.value > -MAX_MODAL_HEIGHT * 0.5) {
        translateY.value = withSpring(0, {damping: 15});
        // 直接用runOnJS包裹rollDown调用,确保在JS线程执行
        runOnJS(rollDown)();
      } else {
        translateY.value = withSpring(-MAX_MODAL_HEIGHT, {damping: 15});
      }
    });

  const rBottomSheetStyle = useAnimatedStyle(() => {
    return {
      transform: [{translateY: translateY.value}]
    };
  }, [translateY]);

  // 移除多余的callRollDown worklet定义
  // ... 组件剩余渲染逻辑
});

额外检查点

  • 确认rollDown函数内部没有直接操作Reanimated的共享值(比如sharedValue.value),如果有这类操作,需要把相关逻辑移到worklet中,或者用runOnUI处理。
  • 确保rollDown是一个纯粹的JS线程操作,比如更新父组件的state、触发普通React回调等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:42:25