flp*_*ppv 6 reactjs react-router react-router-v4 react-router-dom react-router-v5
我在Web和SO上搜索了很多内容,在reactiflux聊天中询问,但是没有找到一种干净的,没有漏洞的方法来根据路径/路径呈现某些组件。
假设我有<Header />应该显示在某些页面上的内容,应该在其他页面上隐藏的内容。
确保可以在Header组件中使用此字符串
if (props.location.pathname.indexOf('/pageWithoutAHeader') > -1) return null
Run Code Online (Sandbox Code Playgroud)
如果/pageWithoutAHeader是唯一的,那完全没问题。如果我需要5页具有相同的功能,它将变为:
if (props.location.pathname.indexOf('/pageWithoutAHeader1') > -1) return null
if (props.location.pathname.indexOf('/pageWithoutAHeader2') > -1) return null
if (props.location.pathname.indexOf('/pageWithoutAHeader3') > -1) return null
Run Code Online (Sandbox Code Playgroud)
是的,我可以将路由存储在数组中并编写一个循环,这将更可重用代码。但这是处理此用例的最好,最优雅的方法吗?
我认为这甚至可能是错误的,例如,如果我不使用路由呈现页面的标题,/xyz而我却使用带有UUID的路由,例如/projects/:id和id=xyzfoo,/projects/xyzfoo则不会显示标题,但应该显示标题。
您可以首先列出没有标题的所有路由,然后在附加交换机中将其他路由分组:
...
<Switch>
<Route path="/noheader1" ... />
<Route path="/noheader2" ... />
<Route path="/noheader3" ... />
<Route component={HeaderRoutes} />
</Switch>
...
HeaderRoutes = props => (
<React.Fragment>
<Header/>
<Switch>
<Route path="/withheader1" ... />
<Route path="/withheader2" ... />
<Route path="/withheader3" ... />
</Switch>
</React.Fragment>
)
Run Code Online (Sandbox Code Playgroud)
从文档:
没有路径的路由总是匹配的。
不幸的是,此解决方案可能存在“未找到”页面的问题。它应该放在 的末尾,HeaderRoutes并且会以Header.
Dhara的解决方案没有这样的问题。但Switch如果 React Router 内部结构发生变化,它可能无法很好地工作:
a 的所有子元素
<Switch>都应该是<Route>或<Redirect>元素。只会呈现与当前位置匹配的第一个孩子。
HOC overRoute不是一个Route本身。但它应该工作正常,因为事实上目前的代码库预计任何React.Element具有相同的道具语义<Route>和<Redirect>拥有。
为了实现DRY规则(避免代码重复)并根据路由实现条件渲染,您应采用以下结构:
步骤1)创建layout(HOC),该布局将返回给定的组件<Header/>并导出
import React from "react"
import { Route } from "react-router-dom"
import Header from "./Header"
export const HeaderLayout = ({component: Component, ...rest}) => (
<Route {...rest} render={(props) => (
<>
<Header/>
<Component {...props} />
</>
)} />
)
Run Code Online (Sandbox Code Playgroud)
步骤2)导入布局并使用它
import React, { Component } from 'react'
import { BrowserRouter, Route, Switch } from "react-router-dom"
import Test1 from './Test1';
import Test2 from './Test2';
import { HeaderLayout } from './HeaderLayout';
export default class Main extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<HeaderLayout path="/test1" component={Test1} />
<Route path="/test2" component={Test2}/>
</Switch>
</BrowserRouter>
)
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
结论:
因此,每当您希望将标题组件与路由定义的组件一起使用时,<HeaderLayout />并且如果您不想使用标题,则只需<Route />在页面中隐藏标题即可。
| 归档时间: |
|
| 查看次数: |
884 次 |
| 最近记录: |