framer-motion、react-motion、react-native-animatable、react-native-reanimated、react-spring 和 react-transition-group 都是用于在 React 应用中实现动画效果的流行库,但它们的设计目标、适用平台和底层机制差异显著。framer-motion 和 react-spring 是通用的声明式动画库,适用于 Web 和部分跨平台场景;react-motion 是早期基于物理模型的动画方案,现已不再积极维护;react-transition-group 专注于组件进入/离开时的状态管理,不直接处理动画细节;而 react-native-animatable 与 react-native-reanimated 则专为 React Native 设计,前者提供简单易用的预设动画,后者通过原生线程驱动高性能复杂交互动画。
在 React 生态中实现流畅动画看似简单,实则涉及渲染线程、声明式抽象、平台差异等深层工程问题。本文将深入剖析六个主流动画库的技术本质、适用边界和真实代码表现,帮助你在架构层面做出精准决策。
Web 项目应排除 react-native-animatable 和 react-native-reanimated —— 它们仅适用于 React Native。同理,React Native 项目无法直接使用 framer-motion(除非通过社区桥接方案,但非官方支持)。react-spring 和 react-transition-group 则同时支持 Web 与 React Native。
此外,react-motion 已被官方标记为废弃(GitHub 仓库归档,README 明确建议迁移到 react-spring),新项目绝不应采用。
这是最常见的 UI 动画需求。各库如何应对?
framer-motion(Web)
import { motion, AnimatePresence } from 'framer-motion';
function FadeComponent({ isVisible }) {
return (
<AnimatePresence>
{isVisible && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
/>
)}
</AnimatePresence>
);
}
react-spring(Web / React Native)
import { useSpring, animated } from 'react-spring';
function FadeComponent({ isVisible }) {
const props = useSpring({
opacity: isVisible ? 1 : 0,
config: { duration: 300 }
});
return <animated.div style={props} />;
}
react-transition-group(Web / React Native)
import { Transition } from 'react-transition-group';
function FadeComponent({ isVisible }) {
return (
<Transition in={isVisible} timeout={300}>
{(state) => (
<div style={{
opacity: state === 'entered' ? 1 : 0,
transition: 'opacity 300ms'
}} />
)}
</Transition>
);
}
react-native-animatable(React Native)
import Animatable from 'react-native-animatable';
function FadeComponent({ isVisible }) {
return (
<Animatable.View
animation={isVisible ? 'fadeIn' : 'fadeOut'}
duration={300}
/>
);
}
💡 关键区别:
framer-motion和react-spring自身驱动动画;react-transition-group仅管理状态,依赖 CSS 实现视觉变化;react-native-animatable提供预设命名动画。
这类高性能交互动画对帧率和响应性要求极高。
framer-motion(Web)
<motion.div
drag="x"
dragConstraints={{ left: -100, right: 0 }}
style={{ x: 0 }}
/>
react-spring(Web / React Native)
import { useDrag } from 'react-use-gesture'; // 需额外依赖
const [{ x }, api] = useSpring(() => ({ x: 0 }));
const bind = useDrag(({ offset: [x] }) => {
api.start({ x: Math.min(0, Math.max(-100, x)) });
});
return <animated.div {...bind()} style={{ x }} />;
react-native-reanimated(React Native)
import { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
function Draggable() {
const translateX = useSharedValue(0);
const gesture = Gesture.Pan()
.onChange((event) => {
translateX.value = Math.min(0, Math.max(-100, event.translationX));
})
.onEnd(() => {
translateX.value = withSpring(0);
});
const style = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }]
}));
return <GestureDetector gesture={gesture}>
<Animated.View style={style} />
</GestureDetector>;
}
💡 关键区别:
framer-motion内置手势支持;react-spring需配合react-use-gesture;react-native-reanimated必须与react-native-gesture-handler联用,并通过useSharedValue在 JS 与原生线程间共享数据。
framer-motion:Web 端使用 requestAnimationFrame + CSS transforms,关键动画属性(如 x, y, scale)直接作用于合成层,避免重排重绘。react-spring:基于弹簧物理模型,通过 rafz(requestAnimationFrame 封装)驱动值更新,支持自定义插值器。react-transition-group:零动画逻辑,仅触发 enter/exit 等状态变更,动画完全由外部 CSS 或样式系统实现。react-native-animatable:通过 Animated API(JavaScript 线程)驱动,复杂动画易掉帧。react-native-reanimated:动画逻辑编译为原生代码,在 UI 线程执行,彻底绕过 JavaScript 线程瓶颈。| 需求 | 推荐方案 | 理由 |
|---|---|---|
| 按钮点击反馈、简单入场动画 | react-native-animatable | 一行代码实现,无需配置原生依赖 |
| 复杂手势(如 Snapchat 式相机滑动) | react-native-reanimated | 唯一能保证 60fps 的方案 |
| 与 React Navigation 转场集成 | react-native-reanimated | 官方导航库深度依赖 Reanimated |
若需同时支持 Web 和 React Native:
react-spring 是唯一提供近乎一致 API 的方案(Web 用 animated.div,RN 用 animated.View)。framer-motion 无 RN 支持;RN 专属库无法用于 Web。framer-motion + react-transition-group 组合。前者处理复杂交互动画,后者管理路由/列表过渡状态。react-native-animatable,复杂交互必须上 react-native-reanimated + react-native-gesture-handler。react-spring 作为统一动画层,但需接受其较重的运行时和学习成本。| 场景 | 推荐库 | 替代方案 |
|---|---|---|
| Web 交互动画(拖拽、手势、共享元素) | framer-motion | react-spring |
| Web 组件进出状态管理 | react-transition-group | 自定义状态机 |
| React Native 简单预设动画 | react-native-animatable | RN 内置 Animated |
| React Native 高性能手势动画 | react-native-reanimated | 无(唯一选择) |
| 跨平台物理模型动画 | react-spring | 分平台实现 |
新项目中的 react-motion | 禁止使用 | 迁移到 react-spring |
最终,没有“最好”的动画库,只有“最合适”当前平台、性能需求和团队能力的工具。理解每个库的底层约束和设计哲学,才能避免在错误的场景中强行使用,导致性能瓶颈或维护噩梦。
选择 framer-motion 如果你需要在 Web 端快速实现声明式、高性能的交互动画(如拖拽、手势、共享元素过渡),且希望 API 简洁直观。它内置了对 SVG、布局动画和 Framer 生态的深度支持,适合产品级 Web 应用,但不适用于 React Native。
选择 react-transition-group 如果你只需要管理组件挂载/卸载时的生命周期状态(如进入、退出、完成),并将实际动画交由 CSS 或其他动画库实现。它本身不执行动画,而是提供状态钩子,适合与 CSS-in-JS 或传统 CSS 动画结合使用。
选择 react-native-reanimated 如果你在 React Native 中构建高性能、复杂的手势驱动交互动画(如自定义滚动、拖拽排序、高级转场)。它通过将动画逻辑移至原生线程执行,避免 JavaScript 线程阻塞,但学习曲线陡峭,需熟悉其特有的工作let语法和共享值机制。
选择 react-spring 如果你需要跨平台(Web + React Native)一致的物理模型动画,或要精细控制弹簧参数(张力、摩擦力等)。它采用声明式 API,支持插值和链式动画,适合需要自然动效的场景,但在简单 CSS 过渡场景下可能显得过于重量级。
不要在新项目中使用 react-motion。官方 GitHub 仓库已归档,明确标注为“不再维护”。虽然其基于弹簧物理模型的理念影响深远,但缺乏现代 React 特性支持(如 Concurrent Mode)和性能优化,应优先考虑 react-spring 或 framer-motion 等替代方案。
选择 react-native-animatable 如果你在 React Native 中需要快速集成简单的预设动画(如淡入、滑动、缩放),且对性能要求不高。它使用 JavaScript 线程驱动,适合轻量级 UI 反馈,但无法处理复杂手势或高帧率交互动画。
npm install motion
Motion is available for React, JavaScript and Vue.
import { motion } from "motion/react"
function Component() {
return <motion.div animate={{ x: 100 }} />
}
Get started with Motion for React.
import { animate } from "motion"
animate("#box", { x: 100 })
Get started with JavaScript.
<script>
import { motion } from "motion-v"
</script>
<template> <motion.div :animate={{ x: 100 }} /> </template>
Get started with Motion for Vue.
Browse 100+ free and 180+ premium Motion Examples, with copy-paste code that'll level-up your animations whether you're a beginner or an expert.
A one-time payment, lifetime-updates membership:
Motion is sustainable thanks to the kind support of its sponsors.
Motion powers the animations for all websites built with Framer, the web builder for creative pros. The Motion website itself is built on Framer, for its delightful canvas-based editing and powerful CMS features.
Motion drives the animations on the Cursor homepage, and is working with Cursor to bring powerful AI workflows to the Motion examples and docs.