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;
关键修正点
- 修复useEffect依赖:原代码中
useEffect未加依赖数组,会导致组件重复渲染并发起多次请求,添加[]确保仅在组件挂载时请求一次数据。 - 修正axios响应处理:原代码直接使用
setBooks(data),正确写法应为setBooks(response.data),因为axios返回的响应对象中data字段才是服务端返回的实际数据。
内容的提问来源于stack exchange,提问作者user20459171
相关产品推荐
相关产品推荐

