

一、AnimatePresence 核心机制与常见用法
1.1 它是干嘛的?
AnimatePresence 是 Framer Motion 提供的一个“退出动画管理器”。React 默认在组件卸载时会立即从 DOM 移除,而 AnimatePresence 可以 拦截卸载动作并播放退出动画。
实现逻辑:
- 检测子元素是否被卸载
- 阻止元素立即卸载,等待退出动画完成后再从 DOM 中移除
- 播放
exit动画 - 动画完成后彻底移除元素
import { motion, useAnimate, useMotionValue, useSpring, useTransform, animate, AnimatePresence } from "motion/react";
<AnimatePresence>
{isVisible && (
<motion.div
initial={
{ opacity: 0 }}
animate={
{ opacity: 1 }}
exit={
{ opacity: 0 }}
>Hello</motion.div>
)}
</AnimatePresence>
1.2 常用配置参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
mode |
"sync" |
"wait" |
onExitComplete |
() => void |
所有退出动画完成后的回调函数 |
initial |
boolean |
是否初始渲染也播放动画(默认 true) |
推荐配置:当你做路由动画或模态框时使用 mode="wait",可避免动画冲突。
二、Modal 弹窗动画实战
2.1 高级模态弹窗动画 + 背景遮罩
以下是一个结合 AnimatePresence 和 motion 实现的模态弹窗组件示例,具备背景遮罩、滚动锁定、点击关闭、ESC 键关闭等完整交互:
const Modal = ({ isOpen, onClose }) => {
useEffect(() => {
// 页面打开时锁定滚动,关闭时恢复
document.body.style.overflow = isOpen ? "hidden" : "auto";
return () => {
document.body.style.overflow = "auto";
};
}, [isOpen]);
useEffect(() => {
const handleKeyDown = (e) => {
if (e.key === "Escape") {
onClose();
}
};
if (isOpen) {
window.addEventListener("keydown", handleKeyDown);
}
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, [isOpen, onClose]);
return (
<AnimatePresence mode="wait">
{isOpen && (
<motion.div
key="modal-backdrop"
className="backdrop"
initial={
{ opacity: 0 }}
animate={
{ opacity: 1 }}
订阅 FreeMac
每周精选:Mac 高效技巧、免费替代付费软件、开发者工具推荐。用对你的 MacBook,省钱 + 提效。