reactjs - React-Router V6 中的递归好友路由
这个 React-Router V5 递归路由示例正好展示了我想要实现的内容:https://v5.reactrouter.com/web/example/recursive-paths
然而,我正在使用 react-router-dom@6,并且在将我的代码转换为 V6 后,输出结果并不是我所期望的。
import {
Routes,
Route,
Link,
useParams,
Outlet,
} from "react-router-dom";
export default function RecursiveExample() {
return (
<>
<Routes>
<Route path="/:id" element={<Person />} />
</Routes>
</>
);
}
function Person() {
let { id } = useParams();
let person = find(parseInt(id as string, 10));
return (
<div>
<h3>{person!.name}’s Friends</h3>
<ul>
{person!.friends.map(id => (
<li key={id}>
<Link to={`${id}`}>{find(id)?.name}</Link>
</li>
))}
</ul>
{/* Outlet will render any nested routes */}
<Outlet />
</div>
);
}
const PEEPS = [
{ id: 0, name: "Michelle", friends: [1, 2, 3] },
{ id: 1, name: "Sean", friends: [0, 3] },
{ id: 2, name: "Kim", friends: [0, 1, 3] },
{ id: 3, name: "David", friends: [1, 2] }
];
function find(id:any) {
return PEEPS.find(p => p.id === id);
}
当点击链接到下一个人 id 时,我在控制台得到错误 "No routes matched location "/0/1" "
我如何在递归渲染这些路由的同时,仍然保持与 V5 示例中相同的 URL 结构,例如 "host.com/1/3/2/..."?
答案#1
问题在于,你假设根路由正在渲染嵌套路由(即一个Route直接渲染另一个Route),而实际上你渲染的是子孙路由(一个路由组件渲染另一个Routes和Route组件)。通过只渲染一个路由和一个出口,你无法深入超过一级,例如,你只能渲染根层路由,任何更深的路径都没有匹配的路由,例如你看到的不变量错误。
Routes 组件取代了 RRDv5 的 Switch 组件,因此了解到在 RRDv5 的递归路径演示中,每个 Person 组件都在渲染子路由,那么 RRDv6 的对应做法是让 Person 渲染另一个 Routes 和递归 Route 组件。RRD v5 和 v6 之间的另一个主要区别是,为了使子路由可匹配并可渲染,其父路由必须在路径末尾添加通配符 "*",或称 splat 匹配器。
示例:
export default function RecursiveExample() {
return (
<Routes>
<Route index element={<Navigate to="/0" replace />} />
<Route path="/:id/*" element={<Person />} />
</Routes>
);
}
function find(id?: string | number) {
return PEEPS.find(p => String(p.id) === String(id));
}
function Person() {
const { id } = useParams();
const person = find(id);
return (
<div>
<h3>{person!.name}’s Friends</h3>
<ul>
{person!.friends.map(id => (
<li key={id}>
<Link to={`${id}`}>{find(id)?.name}</Link>
</li>
))}
</ul>
<Routes>
<Route path="/:id/*" element={<Person />} />
</Routes>
</div>
);
}