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

React Native Reanimated通过forwardRef传递useAnimatedGestureHandler失效咨询

问题原因及修复方案

该问题属于写法错误,并非React Native Reanimated库的缺陷,核心错误有两处:

  • forwardRef接收的ref参数本身就是你在父组件传入的handlerRef,不需要额外访问.handlerRef属性,原代码中ref?.handlerRef?.current属于多余的嵌套取值,实际直接取ref?.current即可。
  • 你将两个子组件UsingHandlerDirect、UsingHandlerForwardRef定义在了App组件内部,每次App重渲染都会重新生成这两个组件的构造函数,导致组件卸载重挂载,状态和事件绑定失效,需要将子组件提到App组件外部定义。

此外你原代码中的手势逻辑也存在小问题:直接给y.value赋值translationY会导致每次拖动时方块从初始位置0开始计算,需要配合ctx.startY承接上一次拖动结束的位置。

修正后的完整代码如下:

// 子组件提到App外部定义
const UsingHandlerDirect = ({ handler, animatedStyles }) => (
  <PanGestureHandler onGestureEvent={handler} >
    <Animated.View style={[styles.blueBox, animatedStyles]} />
  </PanGestureHandler>
)

const UsingHandlerForwardRef = forwardRef(({animatedStyles}, ref) => (
  // 去掉多余的handlerRef层级,直接取ref.current
  <PanGestureHandler onGestureEvent={ref?.current}>
    <Animated.View style={[styles.redBox, animatedStyles]} />
  </PanGestureHandler>
));
// 给forwardRef组件设置displayName便于调试
UsingHandlerForwardRef.displayName = 'UsingHandlerForwardRef';

const App = () => {
  const handlerRef = useAnimatedRef();
  const y = useSharedValue(0);

  handlerRef.current = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      ctx.startY = y.value;
    },
    onActive: ({translationY}, ctx) => {
      // 修复拖动位置计算逻辑
      y.value = ctx.startY + translationY;
    },
    onEnd: () => {},
  });

  const animatedStyles = useAnimatedStyle(() => ({transform: [{translateY: withSpring(y.value)}]}));

  return (
    <SafeAreaView>
      <View style={styles.container}>
        <UsingHandlerForwardRef ref={handlerRef} animatedStyles={animatedStyles}/>
        <UsingHandlerDirect handler={handlerRef.current} animatedStyles={animatedStyles}/>
      </View>
    </SafeAreaView>
  );
}

优化建议

实际上不需要用useAnimatedRef存储手势handler,直接将handler作为props传递给子组件是更简洁、更符合React规范的写法,forwardRef更适合需要传递DOM/原生组件引用的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 18:06:06