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

如何在页面过渡中使用AnimatePresence且不影响嵌套子元素

解决AnimatePresence影响内部Framer Motion动画的问题

问题根源

你设置的AnimatePresence initial={false}是全局生效的,会强制禁用其所有后代motion组件的初始动画,包括页面内嵌套的其他motion元素,这就是导致后续动画失效的原因。

推荐解决方案:条件化控制页面过渡组件的初始动画

移除AnimatePresence上的initial={false},转而在页面过渡的motion.div上通过状态判断,仅在路由切换时触发初始动画,首次加载时跳过。这样既保留了页面切换的过渡效果,又不会影响内部其他motion组件的动画。

代码实现(Next.js _app.js中)

import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { AnimatePresence, motion } from 'framer-motion';

export default function App({ Component, pageProps }) {
  const router = useRouter();
  const [isFirstLoad, setIsFirstLoad] = useState(true);

  useEffect(() => {
    // 路由初始化完成后,标记为非首次加载
    if (router.isReady) {
      setIsFirstLoad(false);
    }
  }, [router.isReady]);

  return (
    <AnimatePresence
      mode="wait"
      onExitComplete={() => {
        window.scrollTo(0, 0);
        setLoaderVisible(false);
      }}
    >
      {/* 用路由路径作为key,确保路由切换时触发组件卸载/挂载 */}
      <motion.div
        key={router.asPath}
        // 首次加载时跳过初始动画,路由切换时启用
        initial={isFirstLoad ? false : { opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        transition={{
          type: 'easeInOut',
          duration: 0.5
        }}
      >
        <Component {...pageProps} />
      </motion.div>
    </AnimatePresence>
  );
}

备选方案:手动覆盖内部组件的初始动画

如果你不想修改AnimatePresence的配置,可以给页面内需要保留初始动画的motion组件,手动指定initial属性(具体状态或true),以此覆盖AnimatePresence的全局禁用规则。

示例:

// 内部嵌套的motion组件,不受AnimatePresence影响
<motion.div
  initial={{ scale: 0 }}
  animate={{ scale: 1 }}
  transition={{ duration: 0.3 }}
>
  页面内动画元素
</motion.div>

注:此方案需要逐个修改内部motion组件,适合动画数量较少的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:07:28