J'ai un composant AdminNav
qui a un ensemble d'éléments NavLink
afin que je puisse les styler s'ils sont actifs.React Router 4 match propriété
Les sections peuvent également être ouvertes/fermées manuellement pour apparaître moins encombrées.
Ce que je voudrais faire est d'avoir un tas de sections dans le nav, et que la section soit ouverte si elle a un NavLink
qui est actif.
AdminNav.js Composant de navigation. Fondamentalement, une liste de 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)
Donc, si je vais à admin/
, la section Cart
ouvre comme prévu. Si je vais à admin/view-orders
, la section Cart
comme prévu. Toutefois, si je vais à admin/view-orders/123
aucun chemin pour le tableau NavLink
ne correspond à la section open
.
adminRoutes.js Ceci est juste un fichier de routage qui stocke toutes mes routes d'administration. Ce n'est pas entièrement montré ici.
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 La route admin mère. Cela a le AdminNav
, et la voie de la volonté de l'une des routes enfant admin comme décrit dans 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
Y at-il une meilleure façon d'aller à ce sujet? Est-ce que je peux accéder à l'itinéraire complet correspondant de ce composant? Ou est-ce
Je ne suis pas sûr que ce soit juste une faute de frappe sur stackoverflow ou un type dans votre système qui pourrait être la raison pour laquelle les routes ne fonctionnent pas. Vous avez '' '' '' admin/view-order/123''' comme URL et '' '"/admin/view-orders /: id? "' '' Comme route. L'URL est au singulier '' '' order''' et la route est configurée au pluriel - '' 'view-orders''' –
Typo. Mise à jour de la question Pardon! – Gurnzbot