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

如何在Loader组件动画结束后加载React Router的GamesPage组件?

实现方案:Loader动画结束后加载GamesPage组件

这里提供两种更可靠的实现思路,优先推荐利用framer-motion的动画完成回调(比固定setTimeout更精准,避免动画时长波动导致的不同步),同时也会给出基于setTimeout的实现方式。

方案一:利用framer-motion的onComplete回调(推荐)

这种方式直接绑定动画的实际结束时机,不会因为性能波动或动画序列变化出现偏差。

1. 修改Loader组件,添加动画完成回调

// Loader.jsx
import { motion } from 'framer-motion';

const Loader = ({ onAnimationFinish }) => {
  // 定义动画变体,包含完整的进入+退出序列
  const loaderVariants = {
    initial: { opacity: 0, scale: 0.8 },
    animate: { 
      opacity: 1, 
      scale: 1,
      transition: { duration: 1.2 }
    },
    exit: {
      opacity: 0,
      scale: 0.8,
      transition: { duration: 0.8 },
      // 动画退出完成时触发外部回调
      onComplete: () => onAnimationFinish?.()
    }
  };

  return (
    <motion.div
      variants={loaderVariants}
      initial="initial"
      animate="animate"
      exit="exit"
      className="fixed inset-0 flex items-center justify-center bg-white"
    >
      <motion.div 
        className="w-24 h-24 border-4 border-blue-500 border-t-transparent rounded-full"
        animate={{ rotate: 360 }}
        transition={{ repeat: Infinity, duration: 1.5, ease: "linear" }}
      />
    </motion.div>
  );
};

export default Loader;

2. 路由跳转逻辑处理

如果你的首页就是Loader页面,动画完成后直接跳转到/games:

// Home.jsx(首页)
import { useNavigate } from 'react-router-dom';
import Loader from './Loader';

const Home = () => {
  const navigate = useNavigate();

  const handleLoaderFinish = () => {
    // 动画完全结束后跳转至游戏页面
    navigate('/games');
  };

  return <Loader onAnimationFinish={handleLoaderFinish} />;
};

export default Home;

然后在App的路由配置中直接映射:

// App.jsx
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './Home';
import GamesPage from './GamesPage';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/games" element={<GamesPage />} />
      </Routes>
    </Router>
  );
}

export default App;

方案二:基于setTimeout的固定延迟实现

如果必须使用setTimeout,需要确保延迟时间大于等于Loader动画的总时长(进入+退出):

1. 自定义延迟路由组件

// DelayedRoute.jsx
import { useState, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import Loader from './Loader';

const DelayedRoute = ({ element, delay = 2000 }) => {
  const [isLoading, setIsLoading] = useState(true);
  const location = useLocation();

  useEffect(() => {
    // 路由切换时重置状态并启动定时器
    setIsLoading(true);
    const timer = setTimeout(() => {
      setIsLoading(false);
    }, delay);

    // 清理定时器,避免内存泄漏
    return () => clearTimeout(timer);
  }, [location, delay]);

  return isLoading ? <Loader /> : element;
};

export default DelayedRoute;

2. 路由配置中使用自定义组件

// App.jsx
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import DelayedRoute from './DelayedRoute';
import GamesPage from './GamesPage';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<DelayedRoute element={<GamesPage />} delay={2000} />} />
        {/* 或者直接给/games路由加延迟 */}
        <Route path="/games" element={<DelayedRoute element={<GamesPage />} delay={2000} />} />
      </Routes>
    </Router>
  );
}

export default App;

注意事项

  • 若使用setTimeout,延迟时间要设置为Loader动画的总时长(进入动画时长+退出动画时长),否则会出现动画未结束就切换页面的情况。
  • 利用onComplete回调的方式更贴合动画实际执行情况,适合复杂动画序列场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:01:19