react实现组件切换动画
使用 React Transition Group 实现组件切换动画
React Transition Group 是一个官方推荐的动画库,提供基础的动画组件和钩子,适合实现组件切换动画。
安装依赖:
npm install react-transition-group
使用 CSSTransition 组件:
import { CSSTransition } from 'react-transition-group';
function App() {
const [show, setShow] = useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>
Toggle
</button>
<CSSTransition
in={show}
timeout={300}
classNames="fade"
unmountOnExit
>
<div className="box">
Content to animate
</div>
</CSSTransition>
</div>
);
}
添加 CSS 样式:
.fade-enter {
opacity: 0;
}
.fade-enter-active {
opacity: 1;
transition: opacity 300ms;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transition: opacity 300ms;
}
使用 Framer Motion 实现高级动画
Framer Motion 提供更强大的动画功能,适合复杂动画场景。
安装依赖:
npm install framer-motion
基本实现:
import { motion, AnimatePresence } from 'framer-motion';
function App() {
const [show, setShow] = useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>
Toggle
</button>
<AnimatePresence>
{show && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
>
Content to animate
</motion.div>
)}
</AnimatePresence>
</div>
);
}
使用 React Spring 实现物理动画
React Spring 基于物理属性实现动画,适合需要自然运动效果的场景。
安装依赖:
npm install react-spring
基本实现:
import { useTransition, animated } from 'react-spring';
function App() {
const [show, setShow] = useState(false);
const transitions = useTransition(show, {
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
config: { duration: 300 },
});
return (
<div>
<button onClick={() => setShow(!show)}>
Toggle
</button>
{transitions((style, item) =>
item && (
<animated.div style={style}>
Content to animate
</animated.div>
)
)}
</div>
);
}
路由切换动画实现
在 React Router 中实现路由切换动画:
import { Switch, Route, useLocation } from 'react-router-dom';
import { AnimatePresence } from 'framer-motion';
function App() {
const location = useLocation();
return (
<AnimatePresence exitBeforeEnter>
<Switch location={location} key={location.pathname}>
<Route exact path="/">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
Home Page
</motion.div>
</Route>
<Route path="/about">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
About Page
</motion.div>
</Route>
</Switch>
</AnimatePresence>
);
}
性能优化建议
避免在动画组件中使用复杂的渲染逻辑,减少不必要的重新渲染。
对于列表动画,使用 key 属性确保动画正确触发:
<AnimatePresence>
{items.map(item => (
<motion.div
key={item.id}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
{item.content}
</motion.div>
))}
</AnimatePresence>
考虑使用 will-change CSS 属性优化性能:
.animated-element {
will-change: transform, opacity;
}






