关于 react-native-reanimated
react-native-reanimated 是面向 React Native 开发者的 UI 线程动画库,提供共享值、动画样式、声明式转场和手势集成,并包含性能与减少动态效果的无障碍指导。
主要功能
- 01在 UI 线程运行动画
- 02根据共享值创建动画样式
- 03使用声明式进入和退出转场
- 04组合定时、弹簧和序列动画
- 05遵循减少动态效果偏好
适用场景
- 01制作 React Native 屏幕转场动画
- 02以错开动效展示列表项
- 03构建手势驱动的动画交互
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dralgorhythm/ claude-agentic-framework --skill react-native-reanimated安装后在 Claude Code 中输入/react-native-reanimated确认已加载。
详细介绍
React Native Reanimated
概述
适用于 React Native 的 UI 线程动画库。Reanimated 4.x 在原生 UI 线程上运行动画,确保达到 60fps 的性能,可在移动应用中替代 Framer Motion。提供共享值、动画样式、声明式进入/退出过渡以及手势集成。
安装:pnpm add react-native-reanimated(包含在 Expo SDK 54+ 中)
工作流
为屏幕添加动画:
- 从
react-native-reanimated导入:Animated、useSharedValue、useAnimatedStyle、withTiming - 为需要动画的属性创建共享值
- 使用
useAnimatedStyle定义动画样式 - 将其应用到
Animated.View、Animated.Text等组件 - 检查
useReducedMotion(),如果结果为 true,则跳过动画 - 在设备上测试,确保动画流畅达到 60fps
添加进入/退出过渡:
- 导入布局动画:
FadeInDown、FadeOutUp、SlideInRight等 - 在
Animated.View上应用entering和exiting属性 - 链式调用修饰符:
.duration(300).easing(...).delay(100) - 确认已处理减少动态效果的偏好
指南
核心基元
useSharedValue(initialValue):在 UI 线程上运行的可变值useAnimatedStyle(() => ({...})):根据共享值派生样式对象withTiming(toValue, config):基于时长的动画withSpring(toValue, config):基于物理效果的弹簧动画withDelay(ms, animation):延迟启动动画withSequence(...animations):按顺序运行动画withRepeat(animation, count, reverse):重复动画
标准计时配置
与 demo-development.md 中的时长保持一致:
| 类型 | 时长 | 用途 |
|---|---|---|
| 快速 | 150ms | 微交互、触觉反馈 |
| 常规 | 300ms | 默认过渡、进入动画 |
| 慢速 | 500ms | 强调效果、屏幕过渡 |
| 错开偏移 | 每项 50ms | 列表项依次显示 |
缓动:进入动画使用 Easing.out(Easing.cubic),过渡使用 Easing.inOut(Easing.cubic),退出动画使用 Easing.in(Easing.cubic)。
声明式进入/退出动画
直接应用到 Animated.View 上——无需父级包装器(与 AnimatePresence 不同):
- 进入:
FadeIn、FadeInDown、FadeInUp、SlideInRight、ZoomIn - 退出:
FadeOut、FadeOutUp、FadeOutDown、SlideOutLeft、ZoomOut - 链式调用修饰符:
.duration(300)、.delay(100)、.easing(Easing.out(Easing.cubic)) - 弹簧效果:
.springify().damping(15).stiffness(150)
错开模式
使用 withDelay 并乘以索引:
entering={FadeInDown.delay(index * 50).duration(300)}
或者用于命令式动画:
offset.value = withDelay(index * 50, withTiming(1, { duration: 300 }))
无障碍 — 减少动态效果
始终尊重用户的无障碍偏好:
const reducedMotion = useReducedMotion();
当 reducedMotion 为 true 时:
- 跳过所有动画(立即设置值)
- 使用
duration(0),或不应用进入/退出属性 - 仍然显示内容,只是不为其添加动画
动画组件
使用 Animated.View、Animated.Text、Animated.ScrollView 等。也可以创建动画版本:
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
性能
- 仅对
transform和opacity添加动画——这些属性在 UI 线程上运行 - 避免对
width、height、margin、padding添加动画(会导致布局重新计算) - 共享值在 UI 线程上更新,不会产生 JS bridge 开销
useAnimatedStyleworklet 在 UI 线程上运行——保持其纯粹性- 对于列表,为列表项使用
entering/exiting,而不是为容器添加动画
最佳实践
- 使用声明式的
entering/exiting实现挂载/卸载动画——比手动使用共享值更简单 - 拖动、手势等交互优先使用
withSpring,效果更自然 - 屏幕进入、淡入等 UI 过渡优先使用
withTiming - 应用动画前,务必检查
useReducedMotion() - 保持标准时长一致:150ms / 300ms / 500ms
- 使用
withDelay(index * 50, ...)实现列表元素的交错显示 - 与
react-native-gesture-handler结合使用,实现手势驱动的动画 - 将
Easing.out(Easing.cubic)作为进入动画的默认缓动函数
反模式
- 使用 React Native 内置的
AnimatedAPI,而不是 Reanimated - 对布局属性(
width、height、margin)应用动画——请使用transform和opacity - 忘记进行
useReducedMotion()无障碍检查 - 在
useAnimatedStyle工作区中运行大量占用 JS 线程的逻辑 - 将时长硬编码(请使用常量:150/300/500ms)
- 不必要地嵌套过多动画视图(会带来性能开销)
- 使用
setTimeout实现交错效果,而不是withDelay - 未在真实设备上测试就应用进入动画
评论
支持 Markdown