我正在从 React Router v5 迁移到 React Router v6。新版本的主要变化之一是
path
属性不接受数组。
所以原始代码与此类似:
<Route path=["/a-route", "/another-route", "/another-more", "/even-other">
<VeryBigChildren>....</VeryBigChildren>
<Route/>
它必须重构为类似的东西:
<Route path="/a-route" element={<VeryBigChildren>...</VeryBigChildren>} />
<Route path="/another-route" element={<VeryBigChildren>...</VeryBigChildren>} />
<Route path="/another-more" element={<VeryBigChildren>...</VeryBigChildren>} />
<Route path="/even-other" element={<VeryBigChildren>...</VeryBigChildren>} />
我认为这很令人讨厌,难以阅读且难以维护。
所以我创建了一个小组件:
export const MultipleRoute = ({ path, children }) => (
<>
{path.map((routePath) => (
<Route key={routePath} path={routePath} element={<>{children}</>} />
))}
</>
);
能够将原始代码重构为:
<MultipleRoute path=["/a-route", "/another-route", "/another-more", "/even-other">
<VeryBigChildren>....</VeryBigChildren>
<MultipleRoute/>
然而,react-router 抱怨
<MultipleRoute>
不是 <RouteS>
组件的有效子组件:
那么,有没有机会创建一个有效的路由子组件?
MultipleRoute
渲染的路由必须包装在Routes
组件中,并且MultipleRoute
必须由Route
组件本身渲染。只有 Route
组件可以是 Route
组件的有效子组件,因此 MultipleRoute
需要采用您想要在每个路由上渲染的 JSX。
示例:
<Route
path="/*" // <-- Splat "*" is necessary for descendent routes to render
element={(
<MultipleRoute
path={[
"/a-route",
"/another-route",
"/another-more",
"/even-other"
]}
element={<VeryBigChildren />}
/>
)}
/>
export const MultipleRoute = ({ path, element }) => (
<Routes>
{path.map((routePath) => (
<Route key={routePath} path={routePath} element={element} />
))}
</Routes>
);
虽然你认为直接渲染 4 条路线是“令人讨厌、难以阅读、难以维护”,但与上面的代码相比,我不同意。大约需要两倍的代码行数才能完成更少的任务。 4条路线直达,对比一下:
<Route path="/a-route" element={<VeryBigChildren/ >} />
<Route path="/another-route" element={<VeryBigChildren />} />
<Route path="/another-more" element={<VeryBigChildren />} />
<Route path="/even-other" element={<VeryBigChildren />} />
使用上述“多路由”组件的局限性在于,您只能为每个要匹配的路径指定一个
"/*"
根级路由。如果您想对路由进行“分组”以呈现不同的组件,则需要将它们嵌套在其他根级路由下。
示例:<Route
path="/*"
element={(
<MultipleRoute
path={[...]}
element={<RootChildren />}
/>
)}
/>
<Route
path="/foo/*"
element={(
<MultipleRoute
path={[...]}
element={<FooChildren />}
/>
)}
/>
由于这种复杂性,您最好只实现正常的下降路线。
示例:
<Route path="/*" element={<RootChildren />} />
<Route path="/foo/*" element={<FooChildren />} />
const RootChildren = () => (
<Routes>
<Route path="/a-route" element={<VeryBigChildren/ >} />
<Route path="/another-route" element={<VeryBigChildren />} />
<Route path="/another-more" element={<VeryBigChildren />} />
<Route path="/even-other" element={<VeryBigChildren />} />
</Routes>
);
const FooChildren = () => (
<Routes>
....
</Routes>
);