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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:09:30