You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Framer Motion退出动画失效排查(基于React与Animate Presence)

问题原因及解决方案:Framer Motion AnimatePresence 退出动画不触发

核心问题分析

你的代码存在两个关键错误,直接导致退出动画无法正常运行:

  1. AnimatePresence 被包裹在条件渲染内部
    当show变为false时,AnimatePresence组件本身会被立即卸载,它根本没有机会监听内部motion组件的卸载过程,自然无法触发退出动画。AnimatePresence必须始终存在于DOM中,才能追踪子组件的挂载/卸载状态。

  2. 退出动画的目标状态无效
    你设置的exit={{ opacity: 1, transition: { duration: 1 } }}没有任何视觉变化(初始与退出状态的opacity一致),即使动画运行了也无法被察觉。

修正后的代码示例

import React from "react";
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";

export default function NotExit() {
  const [show, toggle] = useState(true);

  const MyComponent = ({ isVisible }) => (
    // AnimatePresence 放在条件渲染外部
    <AnimatePresence>
      {isVisible && (
        <motion.div
          key="modal"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0, transition: { duration: 1 } }}
          style={{ width: 100, height: 100, backgroundColor: "blue" }}
        />
      )}
    </AnimatePresence>
  );

  return (
    <div className="relative w-screen h-screen flex flex-col-reverse justify-center items-center">
      <button
        className="bg-purple-600 p-2 rounded text-white"
        onClick={() => toggle(!show)}
      >
        切换显示
      </button>
      // 把 AnimatePresence 移到条件渲染外面
      <AnimatePresence mode="wait">
        {show && (
          <motion.section
            key="cock"
            initial={{ y: 100, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            exit={{ y: 100, opacity: 0, transition: { duration: 1 } }}
            className="w-44 h-44 bg-red-500 rounded-xl"
            transition={{ duration: 1 }}
          />
        )}
      </AnimatePresence>
    </div>
  );
}

关键修复点说明

  • 调整AnimatePresence的位置:确保它始终处于DOM中,只让内部的motion组件进行条件渲染。这样AnimatePresence才能捕获到子组件的卸载事件,触发exit动画。
  • 修正exit动画状态:设置与初始状态对应的退出目标(比如初始y:100,退出也设y:100;初始opacity:0,退出设opacity:0),让动画有明显的视觉变化。
  • 保留mode="wait"(可选):如果需要等待退出动画完成后再卸载组件,mode="wait"可以确保动画执行完毕后再移除DOM元素,避免动画被中断。

内容的提问来源于stack exchange,提问作者ayman dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:50:21