将包装器组件放入反应路由器开关中

Putting wrapper components in react router switch

我需要创建一个仅适用于特定路线的布局。但是,当我使用 Switch 并分隔需要备用布局的路由时,如果我尝试访问一个不存在的页面,它只会将我带到布局中,其中没有任何内容。这是示例代码。

<Switch>
    <Route exact path="/" component={SampleComponent} />
    <TokenLayout>
        <Route path="/some-random-component" component={SomeRandomComponent} />
    </TokenLayout>
    <Route path="*" component={NotFound} />
</Switch>

NotFound 组件从不呈现,而是呈现没有子项的 TokenLayout

关于如何解决这个问题有什么建议吗?

问题

这里的问题是 Switch 组件“呈现与位置匹配的第一个子 <Route><Redirect>。”官方文档没有公开地清楚Route的变体)和Redirect是唯一的Switch 组件的有效子组件。当命中 non-route 或 non-redirect 组件时,路由匹配停止并返回并呈现 that 组件。接下来发生的是嵌套路由呈现 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 属性将 SomeRandomComponent 包装在一个内联函数中,将路由属性传递给 SomeRandomComponent

      <Switch>
        <Route exact path="/" component={SampleComponent} />
        <Route
          path="/some-random-component"
          render={props => (
            <TokenLayout>
              <SomeRandomComponent {...props} />
            </TokenLayout>
          )}
        />
        <Route path="*" component={NotFound} />
      </Switch>