v6 中可选参数的替代方法

Sha*_*eaf 42 react-router react-router-dom

在 v5 中,我们可以?为可选参数添加尾随路由,但与 v6 一样,对相同内容的支持已被删除,那么编写以下代码的替代方法是什么?

<Route path="/cart/:id?" component={<CartPage />} />

Dre*_*ese 66

react-router-dom@6.5.0+

可选段/参数已重新引入库中。文档已更新,但v6.5.0 发行说明也包含详细信息。

上述路由可以合并为一条路由:

<Route path="/cart/:id?" element={<CartPage />} />
Run Code Online (Sandbox Code Playgroud)

编辑 v6 中可选参数的替代方式

react-router-dom@6-6.4.5

在对源代码进行了大量挖掘以了解 RRDv6 与 RRDv5 中的路径解析有何不同,并且除了不再使用之外没有发现任何其他内容后,path-to-regex我打开了存储库的问题部分,发现了这个问题,它直接表明他们不这样做不打算在 v6 中支持可选路径参数。

请参阅常见问题解答:正则表达式路由路径发生了什么?

看来建议的解决方案是渲染 2 条路由来匹配任一路径并渲染相同的组件。

例子:

<Route path="/cart/:id" element={<CartPage />} />
<Route path="/cart/" element={<CartPage />} />
Run Code Online (Sandbox Code Playgroud)

或者

<Route path="/cart">
  <Route index element={<CartPage />} />
  <Route path=":id" element={<CartPage />} />
</Route>
Run Code Online (Sandbox Code Playgroud)

不过,后者实际上只是围绕“/cart”相对路径的语法

  • 只是遇到同样的问题。这很烦人,因为我的解决方案严重依赖可选参数,我现在必须重写很多路由。并不是说它增加了很多不必要的行。 (3认同)
  • 只是为了对这个答案做出贡献,因为它是投票最高的:对可选参数的支持又回到了 6.5.0:https://github.com/remix-run/react-router/releases/tag/react-router%406.5。 0。也许更新答案并添加它是值得的:) (3认同)

Voč*_*čko 7

正如 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>;
};
Run Code Online (Sandbox Code Playgroud)

然后调用它:

<Routes>
    {registerOptionalParams('/component/:param1?/:param2?', <Component/>)}
</Routes>    
Run Code Online (Sandbox Code Playgroud)

对于示例 url/component/:param1?/:param2?和给定组件,<Component/>它会生成以下 jsx 元素:

<Route path="component" element={<Component/>}>
    <Route path=":param1" element={<Component/>}>
        <Route path=":param2" element={<Component/>} />
    </Route>
</Route>
Run Code Online (Sandbox Code Playgroud)

我还创建了可选参数的功能请求(https://github.com/remix-run/react-router/issues/8381),将看看它会得到什么反馈。

  • 这太棒了,而且很有魅力。我确实有一个小建议。为了支持深层嵌套路由,我会将 / 放在字符串 `basePath += \`${params[i]}/\`;` 的末尾。这样,无论深度如何,您都可以调用该函数。 (2认同)