【问题标题】:Pass useAnimatedGestureHandler via forwardRef通过 forwardRef 传递 useAnimatedGestureHandler
【发布时间】:2021-08-28 20:42:27
【问题描述】:

我即将用新的 React Native Reanimated 替换旧的 React Native Animated 库以获得性能问题,但我遇到了一个我无法解决的问题。

在我在网上找到的所有示例中,我看到使用useAnimatedGestureHandler 创建的GestureHandlerAnimated.View 在同一个组件中。实际上,这有时是不可能的。

在我以前的应用程序中,我只是通过 forwardRefGestureHandler 对象传递给组件,但似乎 React Native Reanimated 无法做到这一点。我不知道我是有语法错误还是只是一个错误。

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

  handlerRef.current = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      ctx.startY = y.value;
    },
    onActive: ({translationX, translationY}, ctx) => {
      y.value = translationY;
    },
    onEnd: () => {},
  });

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

  const UsingHandlerDirect = () => (
    <PanGestureHandler onGestureEvent={handlerRef.current} >
      <Animated.View style={[styles.blueBox, animatedStyles]} />
    </PanGestureHandler>
  )

  const UsingHandlerForwardRef = forwardRef(({animatedStyles}, ref) => (
    <PanGestureHandler onGestureEvent={ref?.handlerRef?.current}>
      <Animated.View style={[styles.redBox, animatedStyles]} />
    </PanGestureHandler>
  ));

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

我已将 GestureHandler 保存在 useAnimatedRef handlerRef.current = useAnimatedGestureHandler({}) 中,以使事情更具代表性。然后我将 ref 直接传递到 UsingHandlerDirect 组件的 PanGestureHandler 中。结果是,当我拖动蓝色框时,框将跟随处理程序。所以这个版本有效。

但只要我将handlerRef 传递给UsingHandlerForwardRef 组件,就不会触发手势事件。我希望当我拖动红色框时也会跟随处理程序,但它不会

有人知道是我还是库中的错误?

干杯

【问题讨论】:

    标签: react-native react-forwardref react-native-reanimated-v2


    【解决方案1】:

    我已经放弃了传递 ref 的想法,而是创建了一个挂钩,通过上下文将两个组件相互连接。

    我创建了一个简单的钩子

    
    import { useSharedValue } from 'react-native-reanimated';
    
    const useAppState = () => {
      const sharedXValue = useSharedValue(0);
    
      return {
        sharedXValue,
      };
    };
    
    export default useAppState;
    

    使用复活 2 中的 useSharedValue 保存共享值

    child 组件像这样在gestureHandler 中使用这个值

    
    const gestureHandler = useAnimatedGestureHandler({
        onStart: (_, ctx) => {
          ctx.startX = sharedXValue.value;
        },
        onActive: (event, ctx) => {
          sharedXValue.value = ctx.startX + event.translationX;
        },
        onEnd: (_) => {
          sharedXValue.value = withSpring(0);
        },
      });
    

    Parent 只是消耗钩子值

    const animatedStyle = useAnimatedStyle(() => {
        return {
          transform: [
            {
              translateX: -sharedXValue.value,
            },
          ],
        };
      });
    

    我创建了一个 workable Snack,其中包含两个组件 - 一个带有蓝色框的 Child 和带有红色框的 Parent

    【讨论】:

      猜你喜欢
      • 2020-05-28
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 2013-04-21
      • 2011-08-21
      • 1970-01-01
      • 2020-12-06
      • 2012-04-14
      相关资源
      最近更新 更多