【发布时间】:2021-11-17 13:50:50
【问题描述】:
在 v5 中,我们可以添加尾随 ? 来路由可选参数,但在 v6 中,对相同的支持已被删除,那么编写以下代码的替代方法是什么?
<Route path="/cart/:id?" component={<CartPage />} />
【问题讨论】:
标签: react-router react-router-dom
在 v5 中,我们可以添加尾随 ? 来路由可选参数,但在 v6 中,对相同的支持已被删除,那么编写以下代码的替代方法是什么?
<Route path="/cart/:id?" component={<CartPage />} />
【问题讨论】:
标签: react-router react-router-dom
在对源代码进行了大量挖掘以了解 RRDv6 中的路径解析与 RRDv5 的不同之处之后,除了他们不再使用 path-to-regex 之外,我什么也没发现,我打开了 repo 的问题部分并找到了这个issue 在 v6 中直接声明他们 don't plan to support optional path parameters。
查看常见问题解答:What Happened to Regexp Routes Paths?
似乎建议的解决方案是渲染 2 个路由以匹配任一路径并渲染相同的组件。
例子:
<Route path="/cart/:id" element={<CartPage />} />
<Route path="/cart/" element={<CartPage />} />
或
<Route path="/cart">
<Route index element={<CartPage />} />
<Route path=":id" element={<CartPage />} />
</Route>
后者实际上只是相对路径 from "/cart" 周围的语法糖。
【讨论】:
path 现在也 是一个字符串,所以你甚至不能使用一个路径数组来匹配,你必须非常明确。
正如 Drew Reese 所说,v6 中不支持可选参数(至少目前如此)。
我最终编写了这些为可选参数注册所有嵌套路由的小辅助函数。
const registerOptionalParamRoute = (optionalParams: string[], element: Element) => {
if (optionalParams.length === 0)
return <Fragment/>;
const param = optionalParams[0];
optionalParams.splice(0, 1);
return <Route path={param} element={element}>
{registerOptionalParamRoute(optionalParams, element)}
</Route>;
};
const registerOptionalParams = (path: string, element: JSX.Element) => {
const params = path.split("/");
let basePath = "";
let optionalParams = [];
for (let i = 0; i < params.length; i++) {
if (params[i] === '')
continue;
if (!params[i].includes("?"))
basePath += "/" + params[i];
else
optionalParams.push(params[i].substr(0, params[i].length - 1));
}
return <Route path={basePath} key={basePath} element={element}>
{registerOptionalParamRoute(optionalParams, element)}
</Route>;
};
然后调用它:
<Routes>
{registerOptionalParams('/component/:param1?/:param2?', <Component/>)}
</Routes>
对于示例 url /component/:param1?/:param2? 和给定组件 <Component/>,它会生成以下 jsx 元素:
<Route path="component" element={<Component/>}>
<Route path=":param1" element={<Component/>}>
<Route path=":param2" element={<Component/>} />
</Route>
</Route>
我还为可选参数创建了功能请求 (https://github.com/remix-run/react-router/issues/8381),看看会得到什么反馈。
【讨论】:
basePath += `${params[i]}/`; 的末尾。这样,无论深度如何,您都可以调用该函数。
现在你必须做一些修改并渲染两条路线(有和没有 id)。
【讨论】:
使用通配符:
<Route path="/cart/*" component={<CartPage />} />
【讨论】: