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

React Spring与Next.js页面过渡问题:卸载组件无法淡出

Next.js + React Spring 页面过渡:卸载组件无法淡出问题

在Next.js中使用React Spring实现页面过渡效果时,遇到了卸载的组件直接消失,无法实现淡出动画,但新组件可以正常淡入的问题,效果如下:
页面过渡问题演示

切换后页面还会在下方重新加载,尝试在from或leave属性中添加absolute定位,但没有效果。

原代码

//_app.js

import "../styles/globals.css";
import { useTransition, animated } from "react-spring";
import { useRouter } from "next/router";

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const transition = useTransition(router, {
    key: router.pathname,
    from: { opacity: 0},
    enter: { opacity: 1 },
    leave: { opacity: 0},
    config: { duration: 1000 },
    // reset:true,
  });

  return transition((style, item) => {
    return (
      <animated.div style={style}>
        <Component {...pageProps} />
     </animated.div>
    );
  });

}

export default MyApp;

问题原因及解决办法

核心问题是新旧组件的文档流冲突,以及路由状态监听时机不对,导致旧组件还没完成淡出就被移除。以下是修改后的代码:

//_app.js

import "../styles/globals.css";
import { useTransition, animated } from "react-spring";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const [currentPath, setCurrentPath] = useState(router.pathname);

  // 监听路由开始变化的事件,确保过渡触发时机准确
  useEffect(() => {
    const handleRouteChange = (url) => setCurrentPath(url);
    router.events.on("routeChangeStart", handleRouteChange);
    return () => router.events.off("routeChangeStart", handleRouteChange);
  }, [router]);

  const transition = useTransition(currentPath, {
    key: (path) => path,
    from: { opacity: 0, position: 'absolute', top: 0, left: 0, right: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 },
    config: { duration: 1000 },
  });

  return (
    <div style={{ position: 'relative', minHeight: '100vh' }}>
      {transition((style, path) => (
        <animated.div style={style}>
          <Component {...pageProps} key={path} />
        </animated.div>
      ))}
    </div>
  );
}

export default MyApp;

关键修改点

  • 外层容器添加position: relative和minHeight: 100vh,确保过渡容器占满视口,作为绝对定位的参考容器。
  • 在from属性中设置position: absolute及上下左右定位,让新旧页面组件重叠,避免文档流挤压导致旧组件提前消失。
  • 通过routeChangeStart事件监听路由变化,确保过渡动画在路由切换开始时触发,而非组件卸载后。
  • 给Component添加key={path},让React正确识别页面组件的卸载和挂载,保证过渡逻辑生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:35:10