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

React Router v6服务端加载路由时避免显示NotFound页面

解决React Router v6动态路由加载时NotFound页面闪烁问题

核心原因

初始状态下服务端路由数据还未加载完成,books数组为空,此时path="*"的NotFound路由会匹配所有未定义的路由,包括后续会生成的有效动态路由,导致页面短暂闪烁NotFound内容。

解决方案

方案1:通过加载状态控制NotFound路由渲染

在路由数据加载完成前,不渲染NotFound路由,或临时显示加载提示,避免无效匹配。修改后的代码如下:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import axios from "axios";
import { useState, useEffect } from "react";
import { Books } from "./components/Books";
import { Book } from "./components/Book";
import { Home } from "./components/Home";

const App = () => {
  const [books, setBooks] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    loadBooks();
  }, []);

  function loadBooks() {
    axios.get("http://localhost:3001/books")
      .then((response) => setBooks(response.data))
      .catch(err => console.error("加载路由数据失败:", err))
      .finally(() => setLoading(false));
  }

  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/books">
          <Route index element={<Books />} />
          {books.map((book, index) => (
            <Route
              key={index}
              path={book.name}
              element={<Book name={book.name} />}
            />
          ))}
        </Route>
        {/* 加载完成后才渲染NotFound路由 */}
        {!loading && <Route path="*" element={<h1>Not found!</h1>} />}
        {/* 加载中时对未知路由显示加载提示 */}
        {loading && <Route path="*" element={<h1>加载中...</h1>} />}
      </Routes>
    </Router>
  );
};

export default App;

方案2:用Suspense统一处理加载状态

如果需要对全局路由加载状态做统一管理,可以用React的Suspense组件包裹路由,配合加载提示:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import axios from "axios";
import { useState, useEffect, Suspense } from "react";
import { Books } from "./components/Books";
import { Book } from "./components/Book";
import { Home } from "./components/Home";

const App = () => {
  const [books, setBooks] = useState([]);

  useEffect(() => {
    axios.get("http://localhost:3001/books")
      .then((response) => setBooks(response.data))
      .catch(err => console.error("加载路由数据失败:", err));
  }, []);

  return (
    <Router>
      <Suspense fallback={<h1>加载中...</h1>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/books">
            <Route index element={<Books />} />
            {books.map((book, index) => (
              <Route
                key={index}
                path={book.name}
                element={<Book name={book.name} />}
              />
            ))}
          </Route>
          <Route path="*" element={<h1>Not found!</h1>} />
        </Routes>
      </Suspense>
    </Router>
  );
};

export default App;

关键修正点

  1. 修复useEffect依赖:原代码中useEffect未加依赖数组,会导致组件重复渲染并发起多次请求,添加[]确保仅在组件挂载时请求一次数据。
  2. 修正axios响应处理:原代码直接使用setBooks(data),正确写法应为setBooks(response.data),因为axios返回的响应对象中data字段才是服务端返回的实际数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:42:55