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

Reanimated跨线程同步调用函数报错 useAnimatedGestureHandler的onEnd回调iOS运行异常

问题原因
  • useAnimatedGestureHandler 的所有回调(onStart/onActive/onEnd)默认运行在UI线程,而setHeaderExpanded是React的状态更新方法,只能运行在JS线程,你直接在onEnd里调用跨线程的JS方法,就会触发这个报错。
  • 浏览器环境是单线程的,不存在UI/JS线程隔离,所以逻辑能跑通,iOS原生端有线程隔离就会报错。
修复方案

首先需要从reanimated包导入runOnJS工具,然后修改onEnd回调逻辑,把所有JS线程的方法调用都用runOnJS包裹:

// 顶部先导入runOnJS
import { useSharedValue, useAnimatedStyle, useAnimatedGestureHandler, withTiming, runOnJS } from 'react-native-reanimated'

// 修改onEnd回调
const resizeHeaderHeight = useAnimatedGestureHandler({
    onStart: () => {},
    onActive: (event) => {
        headerHeight.value = event.absoluteY
    },
    onEnd: () => {
        if(headerHeight.value < 305) {
            headerHeight.value  = withTiming(176, {
                duration: 500,
            })
            // 把setHeaderExpanded包在runOnJS里
            runOnJS(setHeaderExpanded)(false)
        } else {
            headerHeight.value  = withTiming(416, {
                duration: 500,
            })
            runOnJS(setHeaderExpanded)(true)
        }   
    },
})
注意事项
  • 不需要给onEnd加'worklet'声明,useAnimatedGestureHandler的回调默认已经是worklet运行在UI线程
  • 所有需要在UI线程回调里调用的非worklet方法(包括React状态更新、自定义JS函数等)都必须用runOnJS包裹,调用格式是runOnJS(你的函数)(参数1, 参数2...),不要写成runOnJS(你的函数(参数)),后者还是会先在UI线程执行函数,依然报错。
  • 如果后续还要在onEnd里加其他自定义JS逻辑,建议把逻辑抽成单独的JS函数,统一用runOnJS调用即可。

内容的提问来源于stack exchange,提问作者Nikulás Óskarsson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:57:03