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>
“容器”元素存在于所有路由上,但我不希望它呈现在“/”路由上。
如何阻止 <div className="container">
在 "/"
路由上呈现?我希望它在除"/"
之外的所有其他路线上呈现。
我找到但不想使用的解决方案是在我的<Switch>
中呈现的每个组件中显式插入带有class="container"
的元素。有没有更好的办法?
【问题讨论】:
【参考方案1】:您应该能够通过nested routes 和"no match route" 实现您的要求。
我们的想法是通过嵌套路由为您的路由引入结构,以将<div className="container">
的呈现限制为非/
路由。
为此,您可以提取一个为路径呈现<Route>
的组件(即WithContainer
); /register
、/login
和 /profiles
,在 <div className="container">
内部。然后,您将更改您的 <Switch>
以现在为以下路线案例呈现两条路线;
-
一个
<Route/>
,它在/
的精确匹配上呈现Landing
组件
一个<Route/>
在没有特定路径(即任何不完全匹配/
的路径)上呈现您的新WithContainer
组件
通过以这种方式使用<Switch>
,它会导致路由行为根据第一个匹配的路由呈现Landing
或WithContainer
(但不能同时呈现两者)。我们利用这种行为来限制“非/
”路由的WithContainer
(以及<div className="container">
元素)的呈现。
在代码中,这种方法可以表示为:
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 保护路由 渲染没有返回任何内容