React Router:如何在所有路由上渲染元素,除了一个?

Posted

技术标签:

【中文标题】React Router:如何在所有路由上渲染元素,除了一个?【英文标题】:React Router: How to render element on all routes, except one? 【发布时间】:2019-11-04 03:29:16 【问题描述】:

我有这样的 html 结构:

<body>
  <nav>
     <!--navigation elements -->
  </nav>
  <div className='main'>
     <!--other elements -->
  </div>
  <div className='container'></div>
</body>

路由定义如下:

<Router>
  <Fragment>
    <Navbar />
    <Route exact path="/" component=Landing />
    <div className="container">
       <Alert />
       <Switch>
           <Route exact path="/register" component=Register />
           <Route exact path="/login" component=Login />
           <Route exact path="/profiles" component=Profiles />
       </Switch>
    </div>
  </Fragment>
</Router>

“容器”元素存在于所有路由上,但我不希望它呈现在“/”路由上。

如何阻止 &lt;div className="container"&gt;"/" 路由上呈现?我希望它在除"/" 之外的所有其他路线上呈现。

我找到但不想使用的解决方案是在我的&lt;Switch&gt; 中呈现的每个组件中显式插入带有class="container" 的元素。有没有更好的办法?

【问题讨论】:

【参考方案1】:

您应该能够通过nested routes 和"no match route" 实现您的要求。

我们的想法是通过嵌套路由为您的路由引入结构,以将&lt;div className="container"&gt; 的呈现限制为非/ 路由。

为此,您可以提取一个为路径呈现&lt;Route&gt; 的组件(即WithContainer); /register/login/profiles,在 &lt;div className="container"&gt; 内部。然后,您将更改您的 &lt;Switch&gt; 以现在为以下路线案例呈现两条路线;

    一个&lt;Route/&gt;,它在/的精确匹配上呈现Landing组件 一个&lt;Route/&gt; 在没有特定路径(即任何不完全匹配/ 的路径)上呈现您的新WithContainer 组件

通过以这种方式使用&lt;Switch&gt;,它会导致路由行为根据第一个匹配的路由呈现LandingWithContainer(但不能同时呈现两者)。我们利用这种行为来限制“非/”路由的WithContainer(以及&lt;div className="container"&gt;元素)的呈现。

在代码中,这种方法可以表示为:

const WithContainer = () => (
    <div className="container">
        /* Wrap routes in container div */ 
       <Route exact path="/register" component=Register />
       <Route exact path="/login" component=Login />
       <Route exact path="/profiles" component=Profiles />
    </div>)

const Main = () => (
  <main> 
    <Switch>
      <Route exact path='/' component=Landing/>
      <Route component= WithContainer  /> /* No match route */ 
    </Switch>
  </main>
)

希望有帮助!

【讨论】:

有效!注意细节:不要忘记在两个组件的“Router”中实现“Switch”。【参考方案2】:

使用最新版本的 React Router,您可以为 path 属性提供字符串数组,以便在多个匹配项上呈现特定路由:

<Route path=['/one', '/two', '/three'] component=SomeComponent />

这里是相关文档的链接:https://reacttraining.com/react-router/web/api/Route/path-string-string。

【讨论】:

【参考方案3】:

如果您不想创建单独的组件,您可以这样做。如果要保留原始功能,还需要保留内部开关。

// parent switch
<Switch>
  <Route exact path="/" component=Landing />
  // start route wrap!!!
  <Route> 
    <div className="container">
      <Switch>
        <Route exact path="/register" component=Register />
        <Route exact path="/login" component=Login />
        <Route exact path="/profiles" component=Profiles />
      </Switch>
    </div>
  </Route>
 // end route wrap!!!
</Switch>

您应该将路由视为任何其他 UI 组件。可以任意嵌套。

【讨论】:

以上是关于React Router:如何在所有路由上渲染元素,除了一个?的主要内容,如果未能解决你的问题,请参考以下文章

使用 react router dom v6 保护路由 渲染没有返回任何内容

尽管所有反应路由器版本冲突,如何在反应中进行服务器端渲染?

如何添加将使用 react-router-dom 渲染组件的路由?

React Router v4 路由参数不渲染/刷新

如何使用 react-router-dom 创建动态路由?

当路由匹配时,React Router 不显示组件(但渲染工作)