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

Next.js 14页面切换过渡仅刷新生效问题求助

解决Next.js 14 Page Router中Framer Motion页面过渡失效问题

问题现象

使用Next.js 14 Page Router,通过MainLayout统一应用Framer Motion页面淡入淡出过渡效果,仅页面刷新时动画生效,通过Link组件切换页面时无任何过渡效果。已添加'use client'并调整AnimatePresence位置,问题仍未解决。

核心问题分析

  1. AnimatePresence无法感知页面切换:原代码中页面组件的key在_app.tsx中定义,但AnimatePresence包裹的motion.div未绑定该key,导致页面切换时AnimatePresence无法识别组件卸载/挂载,无法触发exit动画。
  2. exit动画配置无效:原exit变体的opacity设为1,与初始状态无差异,视觉上看不到淡出效果。
  3. MainLayout未声明为客户端组件:Framer Motion的组件仅能在客户端组件中运行,未添加'use client'会导致动画逻辑无法在客户端执行。

修复方案及代码调整

1. 修正MainLayout.tsx

添加'use client'声明,绑定页面唯一key,修正exit动画配置:

'use client';
import { AnimatePresence, motion } from 'framer-motion';
import Header from './Header';
import Footer from './Footer';

export default function MainLayout({
  children,
  key,
}: {
  children: React.ReactNode;
  key: string;
}) {
  const animation = (variants) => ({
    initial: 'initial',
    animate: 'animate',
    exit: 'exit',
    variants,
  });

  const pagesVariants = {
    initial: {
      opacity: 0,
    },
    animate: {
      opacity: 1,
      transition: {
        duration: 0.6,
      },
    },
    exit: {
      opacity: 0,
      transition: {
        duration: 0.6,
      },
    },
  };

  return (
    <>
      <Header />
      <AnimatePresence mode="wait">
        <motion.div
          id="main"
          className="flex grow flex-col"
          {...animation(pagesVariants)}
          key={key}
        >
          {children}
        </motion.div>
      </AnimatePresence>
      <Footer />
    </>
  );
}

2. 修正_app.tsx

将router.route作为唯一key传递给MainLayout:

import type { AppProps } from 'next/app';
import MainLayout from '../components/MainLayout';
// 导入字体及样式资源...

export default function App({ Component, pageProps, router }: AppProps) {
  return (
    <div
      id="app"
      className={`${amarante.variable} ${metal.variable} ${viaodaLibre.variable} ${philosopher.variable} ${styles.app} font-text`}
    >
      <MainLayout key={router.route}>
        <Component {...pageProps} />
      </MainLayout>
    </div>
  );
}

关键修复点说明

  • 客户端组件声明:'use client'确保Framer Motion的动画逻辑在客户端执行,避免服务端渲染导致的动画失效。
  • 唯一key绑定:通过router.route作为页面唯一标识,每次切换页面时key变化,AnimatePresence会触发旧页面的exit动画和新页面的animate动画。
  • 有效exit动画:将exit变体的opacity设为0,实现页面淡出效果,配合mode="wait"确保前一页动画完成后再加载新页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:23:16