我需要创建一个仅适用于某些路线的布局。但是,当我使用 Switch 并分隔需要备用布局的路线时,如果我尝试访问一个不存在的页面,它只会将我带到其中没有任何内容的布局。这是示例代码。
<Switch>
<Route exact path="/" component={SampleComponent} />
<TokenLayout>
<Route path="/some-random-component" component={SomeRandomComponent} />
</TokenLayout>
<Route path="*" component={NotFound} />
</Switch>
NotFound
组件从不渲染,而是渲染没有子组件的 TokenLayout
。
关于如何解决这个问题的任何建议?
回答1
问题
这里的问题是 https://v5.reactrouter.com/web/api/Switch 组件“呈现与该位置匹配的第一个子 <Route>
或 <Redirect>
”。官方文档并没有明确说明 Route
(及其变体)和 Redirect
是 Switch
组件的唯一有效子级。当一个非路由或非重定向组件被命中时,路由匹配停止并且该组件被返回并呈现。接下来发生的是嵌套路由渲染 SomeRandomComponent
是包容性匹配的,就好像它是由不在 Switch
内的路由器进行的一样。
解决方案
重构代码以在路由内呈现 TokenLayout
组件。
这里有一些建议:
创建一个包装组件
const TokenLayoutWrapper = props => ( <TokenLayout> <SomeRandomComponent {...props} /> </TokenLayout> );
...
<Switch> <Route exact path="/" component={SampleComponent} /> <Route path="/some-random-component" component={TokenLayoutWrapper} /> <Route path="*" component={NotFound} /> </Switch>
创建高阶组件
const withTokenLayout = Component => props => ( <TokenLayout> <Component {...props} /> </TokenLayout> );
装饰
SomeRandomComponent
组件导出:export default withTokenLayout(SomeRandomComponent);
...
<Switch> <Route exact path="/" component={SampleComponent} /> <Route path="/some-random-component" component={SomeRandomComponent} /> <Route path="*" component={NotFound} /> </Switch>
只需使用
render
prop 将SomeRandomComponent
包装在一个内联函数中,将路由 props 传递给SomeRandomComponent
。<Switch> <Route exact path="/" component={SampleComponent} /> <Route path="/some-random-component" render={props => ( <TokenLayout> <SomeRandomComponent {...props} /> </TokenLayout> )} /> <Route path="*" component={NotFound} /> </Switch>