通过 forwardRef 传递 useAnimatedGestureHandler
Pass useAnimatedGestureHandler via forwardRef
我准备将旧的 React Native Animated 库替换为新的 React Native Reanimated 库以解决性能问题,但我遇到了一个我无法解决的问题。
在我在网上找到的所有示例中,我看到使用 useAnimatedGestureHandler
创建的 GestureHandler 与 Animated.View
在同一组件中。事实上,有时这是不可能的。
在我以前的应用程序中,我只是通过 forwardRef
将 GestureHandler 对象传递给组件,但似乎 React Native Reanimated 无法做到这一点。不知道是语法错误还是bug。
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
组件,就不会触发任何手势事件。我希望当我拖动红色框时也会跟随处理程序但它不会
有人知道是我的问题还是库中的错误吗?
干杯
我放弃了传递 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,其中包含 2 个组件 - 一个带有蓝色方框的 Child
和一个带有红色方框的 Parent
我准备将旧的 React Native Animated 库替换为新的 React Native Reanimated 库以解决性能问题,但我遇到了一个我无法解决的问题。
在我在网上找到的所有示例中,我看到使用 useAnimatedGestureHandler
创建的 GestureHandler 与 Animated.View
在同一组件中。事实上,有时这是不可能的。
在我以前的应用程序中,我只是通过 forwardRef
将 GestureHandler 对象传递给组件,但似乎 React Native Reanimated 无法做到这一点。不知道是语法错误还是bug。
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
组件,就不会触发任何手势事件。我希望当我拖动红色框时也会跟随处理程序但它不会
有人知道是我的问题还是库中的错误吗?
干杯
我放弃了传递 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,其中包含 2 个组件 - 一个带有蓝色方框的 Child
和一个带有红色方框的 Parent