如何在React Native Reanimated 2中使用useRef触发入场动画?
React Native Reanimated 2 手动触发入场动画的正确方式
你的错误原因很明确:useAnimatedRef拿到的组件实例上并没有LightSpeedInRight这个方法,entering属性是组件挂载时自动触发的入场动画配置,不能通过ref直接调用。要实现按钮手动触发/重启动画,可采用以下两种正确方式:
方法一:使用 useAnimationState(Reanimated 2.9+ 支持)
这个API专门用来控制预定义动画(比如LightSpeedInRight这类)的播放状态,能轻松实现手动触发、重复播放。
import { Animated, useAnimationState, LightSpeedInRight } from 'react-native-reanimated'; import { Button, StyleSheet } from 'react-native'; export default function App() { // 初始化动画状态:idle(未播放)、playing(播放中) const animationState = useAnimationState({ initial: 'idle', states: { idle: {}, playing: { animation: LightSpeedInRight.duration(600) .springify() .damping(15), onComplete: () => { // 动画结束后重置为idle,方便再次触发 animationState.transitionTo('idle'); }, }, }, }); return ( <> <Animated.View style={styles.box} // 绑定动画状态控制器 entering={animationState} /> <Button title="start" onPress={() => { // 触发动画:切换到playing状态 animationState.transitionTo('playing'); }} /> </> ); } const styles = StyleSheet.create({ box: { width: 100, height: 100, backgroundColor: 'blue', margin: 20, }, });
方法二:手动控制动画值(兼容更早版本的Reanimated)
如果你的Reanimated版本低于2.9,可以手动创建共享值,自定义动画逻辑来模拟LightSpeedInRight的效果:
import { Animated, useSharedValue, useAnimatedStyle, withTiming, withSequence, withDelay } from 'react-native-reanimated'; import { Button, StyleSheet } from 'react-native'; export default function App() { // 定义动画所需的共享值:透明度、X轴偏移、缩放 const opacity = useSharedValue(0); const translateX = useSharedValue(300); const scale = useSharedValue(0.3); // 生成动画样式 const animatedStyle = useAnimatedStyle(() => { return { opacity: opacity.value, transform: [ { translateX: translateX.value }, { scale: scale.value }, ], }; }); // 触发动画的函数 const startAnimation = () => { // 重置初始值,确保每次点击都从初始状态开始 opacity.value = 0; translateX.value = 300; scale.value = 0.3; // 执行动画序列:先延迟,再同时执行透明度、位移、缩放动画 opacity.value = withSequence( withDelay(600, withTiming(1, { duration: 600 })) ); translateX.value = withSequence( withDelay(600, withTiming(0, { duration: 600 })) ); scale.value = withSequence( withDelay(600, withTiming(1, { duration: 600 })) ); }; return ( <> <Animated.View style={[styles.box, animatedStyle]} /> <Button title="start" onPress={startAnimation} /> </> ); } const styles = StyleSheet.create({ box: { width: 100, height: 100, backgroundColor: 'blue', margin: 20, }, });
关键注意点
useAnimatedRef主要用于获取Animated组件的引用,做布局测量、节点操作等,不是用来触发预定义入场动画的。- 如果使用预定义动画(比如
LightSpeedInRight),优先用useAnimationState,代码更简洁,也符合Reanimated的设计规范。
内容的提问来源于stack exchange,提问作者Benjamin Jones
相关产品推荐
相关产品推荐

