0

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

在我在网上找到的所有示例中,我看到使用创建的GestureHandleruseAnimatedGestureHandlerAnimated.View. 实际上,这有时是不可能的。

在我之前的应用程序中,我只是将GestureHandler对象传递给组件,forwardRef但似乎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 直接传递到组件的PanGestureHandlerUsingHandlerDirect。结果是,当我拖动蓝色框时,框将跟随处理程序。所以这个版本有效。

但是一旦我将手势事件传递handlerRefUsingHandlerForwardRef组件,就会触发非手势事件。我希望当我拖动红色框时也会跟随处理程序,但它不会

有人知道是我还是图书馆中的错误?

干杯

4

1 回答 1

0

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

我创建了一个简单的钩子


import { useSharedValue } from 'react-native-reanimated';

const useAppState = () => {
  const sharedXValue = useSharedValue(0);

  return {
    sharedXValue,
  };
};

export default useAppState;

使用useSharedValuefrom reanimated 2保存共享值

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,
        },
      ],
    };
  });

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

于 2021-12-09T04:56:09.180 回答