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

Next.js中加载动画仅首次显示问题求助

解决Next.js路由切换时加载动画不显示的问题

你的问题核心是:MyApp组件仅在应用首次启动时挂载一次,loading状态初始为false,执行一次setLoading(true)后就一直保持true。而Next.js的客户端路由切换不会重新挂载MyApp,所以切换路由时不会触发加载动画的渲染。

修复方案

通过监听Next.js的路由切换事件,在每次路由开始切换时重置loading状态,实现路由切换时显示加载动画:

import React from "react";
import { useRouter } from 'next/router'; // 引入useRouter
import styled from "styled-components";

const Screen = styled.div`
  position: relative;
  height: 100vh;
  width: 100%;
  opacity: 0;
  animation: fade 0.4s ease-in forwards;

  @keyframes fade {
    0% {
      opacity: 0.4;
    }
    50% {
      opacity: 0.8;
    }
    100% {
      opacity: 1;
    }
  }
`;

const Balls = styled.div`
  display: flex;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);

  .ball {
    height: 30px;
    width: 30px;
    border-radius: 50%;
    background: #E60E33;
    margin: 0 60px 0 0;
    animation: oscillate 0.7s ease-in forwards infinite;
  }

  .one {
    animation-delay: 0.5s;
  }
  .two {
    animation-delay: 1s;
  }
  .three {
    animation-delay: 1.5s;
  }

  @keyframes oscillate {
    0% {
      transform: translateY(0);
    }
    50% {
      transform: translateY(20px);
    }
    100% {
      transform: translateY(0);
    }
  }
`;


function MyApp({ Component, pageProps }) {
  const [loading, setLoading] = React.useState(false);
  const router = useRouter(); // 初始化路由实例

  React.useEffect(() => {
    // 路由开始切换时,显示加载动画
    const handleRouteStart = () => {
      setLoading(false);
    };

    // 路由切换完成后,隐藏加载动画(可根据实际加载时间调整延迟)
    const handleRouteComplete = () => {
      setTimeout(() => setLoading(true), 500); // 这里设置短延迟模拟加载
    };

    // 绑定路由事件监听
    router.events.on('routeChangeStart', handleRouteStart);
    router.events.on('routeChangeComplete', handleRouteComplete);

    // 组件卸载时移除监听
    return () => {
      router.events.off('routeChangeStart', handleRouteStart);
      router.events.off('routeChangeComplete', handleRouteComplete);
    };
  }, [router]);

  // 首次加载时的处理
  React.useEffect(() => {
    setTimeout(() => setLoading(true), 5000);
  }, []);

  return (
    <>
      {loading ? (
        <Component {...pageProps} />
      ) : (
        <Screen>
          <Balls>
            <div className="ball one"></div>
            <div className="ball two"></div>
            <div className="ball three"></div>
          </Balls>
        </Screen>
       )}
    </>
  );
}

export default MyApp

关键修改说明

  1. 引入useRouter钩子,获取路由实例并监听routeChangeStart(路由开始切换)和routeChangeComplete(路由切换完成)事件
  2. 路由开始切换时将loading设为false,触发加载动画显示;切换完成后延迟设置loading为true,展示页面
  3. 添加组件卸载时的事件移除逻辑,避免内存泄漏
  4. 保留首次加载的延迟逻辑,确保刷新页面时的加载动画正常工作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 08:05:27