React Native Reanimated 是一个面向 React Native 的 UI 线程动画库。其核心理念是把动画计算放到原生 UI 线程执行,从而保证 60fps 的流畅性能,在移动应用场景中替代 Framer Motion 的角色。安装命令为 pnpm add react-native-reanimated,Expo SDK 54 及以上版本已内置该库。
主要能力
库提供一组核心动画原语:useSharedValue(initialValue) 创建存在于 UI 线程上的可变值;useAnimatedStyle(() => ({...})) 从共享值派生样式对象;withTiming(toValue, config) 实现基于时长的动画;withSpring(toValue, config) 实现基于物理的弹簧动画;withDelay(ms, animation) 为动画添加延迟;withSequence(...animations) 按顺序运行动画;withRepeat(animation, count, reverse) 重复播放动画。
在时长规范上,库建议与 demo-development 保持一致的体系:Fast 150ms 用于微交互与触觉反馈;Normal 300ms 用于默认过渡与进入效果;Slow 500ms 用于强调与屏幕切换;列表项错落出现使用每项 50ms 的错开偏移。缓动方面,进入使用 Easing.out(Easing.cubic),过渡使用 Easing.inOut(Easing.cubic),退出使用 Easing.in(Easing.cubic)。
声明式进入/退出过渡
与 AnimatePresence 不同,这类过渡可直接作用于 Animated.View,无需父级包裹。进入效果包括 FadeIn、FadeInDown、FadeInUp、SlideInRight、ZoomIn;退出效果包括 FadeOut、FadeOutUp、FadeOutDown、SlideOutLeft、ZoomOut。可通过链式修饰符配置,如 .duration(300)、.delay(100)、.easing(...),以及弹簧配置 .springify().damping(15).stiffness(150)。
错落(Stagger)模式
可在进入属性中结合索引乘以固定间隔,例如 entering={FadeInDown.delay(index * 50).duration(300)};也可用命令式写法 offset.value = withDelay(index * 50, withTiming(1, { duration: 300 }))。
无障碍与减弱动态效果
库要求始终尊重用户的无障碍偏好,通过 const reducedMotion = useReducedMotion(); 检测。当该值为 true 时,应跳过所有动画(即时设置值),使用 duration(0) 或不应用进入/退出属性,内容仍需显示,只是不做动画。
动画组件
可直接使用 Animated.View、Animated.Text、Animated.ScrollView 等,也可用 Animated.createAnimatedComponent(Pressable) 将普通组件包装为动画组件。
性能注意事项
应仅对 transform 与 opacity 做动画,因为它们在 UI 线程运行;避免对 width、height、margin、padding 做动画,因为会触发布局重算。共享值在 UI 线程更新,没有 JS 桥接开销;useAnimatedStyle 的 worklet 在 UI 线程运行,需保持纯函数。列表场景应把进入/退出效果加在列表项上,而不是动画化容器。
最佳实践
挂载/卸载动画优先使用声明式进入/退出,比手动管理共享值更简单;拖拽与手势交互优先使用 withSpring,界面过渡(屏幕进入、淡入)优先使用 withTiming;应用动画前始终检查 useReducedMotion();保持 150ms / 300ms / 500ms 的标准时长一致;列表错落使用 withDelay(index * 50, ...);与 react-native-gesture-handler 配合实现手势驱动动画;进入动画默认使用 Easing.out(Easing.cubic)。
需避免的做法
不要使用 React Native 内置的 Animated API 代替 Reanimated;不要动画化布局属性(width、height、margin),改用 transform 与 opacity;不要忘记 useReducedMotion() 无障碍检查;不要在 useAnimatedStyle 的 worklet 中运行 JS 线程繁重逻辑;不要硬编码时长值,应使用 150/300/500ms 常量;不要不必要地嵌套大量动画视图;不要用 setTimeout 实现错落,应使用 withDelay;不要在未于真机测试的情况下应用进入动画。
适用场景
该库适用于为 React Native 屏幕添加动画、实现组件挂载与卸载的过渡效果、构建手势驱动的交互动画,以及需要保证流畅帧率的移动端界面动效开发。