【问题标题】:Alternate way for optional parameters in v6v6 中可选参数的替代方式
【发布时间】:2021-11-17 13:50:50
【问题描述】:

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

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

【问题讨论】:

    标签: react-router react-router-dom


    【解决方案1】:

    在对源代码进行了大量挖掘以了解 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" 周围的语法糖。

    【讨论】:

    • 遇到了同样的问题。这很烦人,因为我的解决方案严重依赖可选参数,我现在必须重写很多路由。并不是说它增加了很多不必要的行。
    • @Vočko 更不用说path 现在也 是一个字符串,所以你甚至不能使用一个路径数组来匹配,你必须非常明确。
    • 如果我能以某种方式利用它,我现在正在研究 useRoutes。我确实有一些类似于我为我的应用程序编写的用于生成菜单和路线的东西。它更复杂,但会尝试弄清楚它是否可以以某种方式与钩子一起使用。
    • 我已经创建了一个功能请求,让我们看看反馈是什么 - github.com/remix-run/react-router/issues/8381
    • 这太丑了。我和@Vočko 在同一条船上。更多行...我想知道他们为什么选择这个
    【解决方案2】:

    正如 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? 和给定组件 &lt;Component/&gt;,它会生成以下 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]}/`; 的末尾。这样,无论深度如何,您都可以调用该函数。
    【解决方案3】:

    现在你必须做一些修改并渲染两条路线(有和没有 id)。

    【讨论】:

      【解决方案4】:

      使用通配符:

      <Route path="/cart/*" component={<CartPage />} />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-21
        • 1970-01-01
        • 2022-09-22
        • 1970-01-01
        • 2013-04-09
        • 2013-05-23
        相关资源
        最近更新 更多