
本文讲解如何在 react router v6 中正确配置多级路由,解决因路由未声明导致的 “no routes matched location” 错误,并实现从首页(/)点击按钮跳转并渲染 quiz 组件(/quiz)的完整流程。
本文讲解如何在 react router v6 中正确配置多级路由,解决因路由未声明导致的 “no routes matched location” 错误,并实现从首页(/)点击按钮跳转并渲染 quiz 组件(/quiz)的完整流程。
在 React Router v6 中,所有可访问的路径必须在顶层 <routes></routes> 中显式声明,动态条件渲染 <route></route>(例如 isClicked && <route ...></route>)是无效的——因为 Router 在初始化时已静态解析所有子 <route></route>,不会响应后续状态变化重新挂载路由。
你当前代码的问题核心在于:
- 主
App.jsx中/quiz路由被注释掉了({/* <route path="/quiz" element="{<Quiz"></route>} /> */}),导致 Router 根本“不认识”/quiz这个路径; - 而在
Fetch.jsx内部嵌套<routes></routes>并尝试条件注册/quiz,违反了 v6 的路由设计原则:嵌套路由必须有父级element包裹,且子<routes></routes>仅用于布局嵌套(如带导航栏的页面),不能用于动态启用/禁用路由。
✅ 正确做法:统一在根 <routes></routes> 中声明所有有效路径,并通过状态控制组件内部逻辑(如传参、显隐),而非控制路由注册。
✅ 推荐解决方案(简洁可靠)
1. App.jsx —— 声明全部静态路由
将 React 应用升级到最新版本,从类组件迁移到 Hooks,并采用并发特性。用于现代化改造 React 代码库、迁移到 React Hooks 或升级到最新
import { Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Fetch />} />
<Route path="/quiz" element={<Quiz />} /> {/* ✅ 解除注释,必须存在 */}
</Routes>
</Router>
);
}
export default App;2. Fetch.jsx —— 使用 useNavigate 实现编程式导航(推荐)
import { useNavigate } from 'react-router-dom';
function Fetch({ catData }) {
const navigate = useNavigate();
const [data, setData] = useState(null);
const handleClick = (cat) => {
// 模拟获取该分类数据(可替换为 API 调用)
const filteredData = catData.filter(c => c.category === cat);
setData(filteredData);
navigate('/quiz'); // ✅ 点击后跳转,Router 自动匹配已声明的 /quiz 路由
};
return (
<>
{[...new Set(catData.map(c => c.category))].sort().map((cat) => (
<div key={cat}>
<button onClick={() => handleClick(cat)}>
{cat}
</button>
</div>
))}
</>
);
}
export default Fetch;3. Quiz.jsx —— 通过 useLocation 或 useLoaderData(v6.4+)接收数据
import { useLocation } from 'react-router-dom';
function Quiz() {
const location = useLocation();
// 若需传递数据,建议使用 state(见下方注意事项)
const data = location.state?.quizData || [];
return (
<div>
<h2>Quiz Page</h2>
<pre class="brush:php;toolbar:false;">{JSON.stringify(data, null, 2)}
);
}
export default Quiz;? 关键注意事项:
- ❌ 不要在组件内动态渲染
<route></route>;Router 只读取顶层<routes></routes>的初始结构; - ✅ 使用
useNavigate()+navigate('/quiz', { state: { data } })安全传递临时数据(state 不出现在 URL 中,刷新会丢失); - ✅ 如需持久化数据,改用 URL search params(
?cat=math)或全局状态(Context / Zustand); - ✅ 若需
/quiz页面复用不同数据,可在App.jsx中统一用 loader(v6.4+ Data APIs)或在Quiz内部根据useParams()或useSearchParams()动态获取。
这样配置后,点击按钮将正确导航至 /quiz,Router 找到已注册的路由并渲染 <quiz></quiz>,彻底解决 No routes matched location "/quiz" 错误。


















