我有一个AdminNav
组件,其中包含一组NavLink
元素,因此如果它们处于活动状态,我可以设置它们的样式。
这些部分也可以手动打开/关闭,看起来不那么混乱。
我想要做的是在导航中有一堆部分,如果它有一个活跃的NavLink
,则打开该部分。
AdminNav.js
导航组件。基本上是NavLink
s。
import React, { Component } from 'react'
import { NavLink, withRouter } from 'react-router-dom'
import _find from 'lodash/find'
import '../../css/sub-nav.css'
class AdminNav extends Component {
constructor(props){
super(props)
// Shows 'admin/' at all times
console.log(props.match)
this.state = {
sectionRoutes: [
{
title: 'Cart',
routes: [
{
title: 'Dashboard',
path: '/admin',
exact: true
},
{
title: 'View Orders',
path: '/admin/view-orders',
exact: false
},
{
title: 'Cart Settings',
path: '/admin/settings',
exact: true
},
{
title: 'Merchant Settings',
path: '/admin/merchant',
exact: true
}
]
},
{
title: 'Products',
routes: [
{
title: 'Add Product',
path: '/admin/product-add',
exact: true
},
{
title: 'Edit Product',
path: '/admin/product-edit',
exact: true
},
{
title: 'Add Category',
path: '/admin/category-add',
exact: true
},
{
title: 'Edit Category',
path: '/admin/category-edit',
exact: true
},
{
title: 'Set Category Order',
path: '/admin/category-order',
exact: true
}
]
},
{
title: 'User',
routes: [
{
title: 'Logout',
path: '/admin/logout',
exact: true
}
]
}
],
openSections: []
}
}
handleSectionClick = (sectionTitle) => {
let titleIndex = this.state.openSections.indexOf(sectionTitle)
if(titleIndex > -1){
this.setState({ openSections: this.state.openSections.filter((title, i) => i !== titleIndex)})
}else{
this.setState({ openSections: [ ...this.state.openSections, sectionTitle ] })
}
}
isSectionOpen(section){
const currentPath = this.props.location.pathname
// Section is open if routh path matches the current path OR section has been manually opened
// THIS DOES NOT WORK IF section is a route that has optional params (Ex. `admin/view-orders/:id?`)
const result = _find(section.routes, route => currentPath === route.path) ||
_find(this.state.openSections, title => title === section.title)
return result
}
render() {
return (
<div className="sub_nav">
<div className="title">Admin Menu</div>
{this.state.sectionRoutes.map(section =>
<div key={section.title} className="nav_section">
<div className={'section_title' + (this.isSectionOpen(section) ? ' open' : '')} onClick={(e) => this.handleSectionClick(section.title)}>{section.title}</div>
<div>
{section.routes.map(route =>
<NavLink key={route.title} activeClassName="active" to={route.path} exact={!!route.exact}>{route.title}</NavLink>
)}
</div>
</div>
)}
</div>
)
}
}
export default withRouter(AdminNav)
因此,如果我转到admin/
,Cart
部分会按预期打开。
如果我按预期转到admin/view-orders
Cart
部分。
但是,如果我转到admin/view-orders/123
没有NavLink
数组匹配的路径,那么该部分就不会添加open
类。
adminRoutes.js 这只是一个存储我所有管理路由的路由文件。这里没有完全显示出来。
import React from 'react'
import AdminDashboard from './AdminDashboard'
import AdminLogout from './AdminLogout'
import AdminOrders from './AdminOrders'
export default [
{
path: "/admin",
exact: true,
render: (props) => (<AdminDashboard {...props} />)
},
{
path: "/admin/logout",
component: AdminLogout
},
{
path: "/admin/view-orders/:id?",
component: AdminOrders
},
{
component: () => <h1 className="no-margin">Page not found</h1>
}
]
Admin.js
父管理员路由。它具有AdminNav
,并将路由到任何管理子路由,如adminRoutes.js
import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom'
import AdminNav from './AdminNav'
import routes from './adminRoutes'
class Admin extends Component {
render() {
return (
<div className="full_body_container">
<div className="sub_nav_wrapper">
<div className="hbs-container-admin-nav">
<AdminNav />
</div>
</div>
<div className="content_wrapper">
{
<Switch>
{routes.map((route, i) => <Route key={i} {...route} />)}
</Switch>
}
</div>
</div>
)
}
}
export default Admin
还有更好的方法吗?我能从这个组件访问实际完全匹配的路由吗?或者是这个
答案 0 :(得分:0)
我认为你需要使用children function prop of routes。
Route
组件将一个函数作为子函数(而不是React)
元素traditionnaly。
以对象作为参数调用此函数。我们在寻找什么
for是{match}属性。如果路线匹配则其值将是
路由传递的经典match
对象,否则为null
。
class App extends Component {
render() {
return (
<Router>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
<Link to="/other">other route</Link>
</header>
<Route path="/" exact>
{({ match }) => {
return <Message />
}}
</Route>
<Route path="/other">
{({ match, ...props }) => {
console.log(match, props);
return <Message text={match ? "this matches" : "does not match"} />
}}
</Route>
</div>
</Router>
);
}
}
在这个例子中,我总是在&#39;其他&#39;中呈现一些东西。路由器,我只是测试路由是否匹配并相应地更新消息。您会看到其他路线从未改变是否匹配。