2017-09-28 7 views
0

구성 요소는 NavLink 구성 요소 집합을 가지고 있으므로 활성화되어 있으면 스타일을 지정할 수 있습니다.대응 라우터 4 일치 속성

섹션을 수동으로 열거 나 닫아 덜 어지럽게 보일 수도 있습니다.

내가 원하는 것은 탐색에 많은 섹션이 있고 활성화 된 섹션이 NavLink 인 경우 열려야합니다.

AdminNav.js 탐색 구성 요소. 기본적으로 NavLink의 목록입니다. 내가 admin/에 가면 예상대로

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) 

는 그래서, 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 상위 관리자 경로.

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 

이것에 대해 갈 수있는 더 나은 방법이 있나요 adminRoutes.js에 설명 된대로이 관리자 아동 노선의에 AdminNav, 의지 경로를 가지고? 이 구성 요소에서 실제로 완전히 일치하는 경로에 액세스 할 수 있습니까? 또는이

+0

stackoverflow에 오타가 있거나 시스템에서 작동하지 않는 라우트의 원인이 될 수있는 유형인지 확실하지 않습니다. 당신은''admin/view-order/123'''을 URL로 사용하고/admin/view-orders/: id? "'''를 루트로 사용합니다. URL은 단 하나의'''order''이고 그 경로는 복수로 구성됩니다 -'''view-orders''가 –

+0

오타입니다. 질문을 업데이트했습니다. 죄송합니다! – Gurnzbot

답변

0

나는 children function prop of routes을 사용해야한다고 생각합니다.

Route 구성 요소는 traditionnaly 요소 반응 대신에 어린이와 같은 기능을 (소요됩니다. 이 함수는 인수로 객체를 호출합니다. 우리가 을 찾고있는 것은 {일치} 속성입니다. 경로와 일치하는 경우 그 값은이 null 될 것입니다, 그렇지 않으면 경로에 의해 전달 된 고전 match 객체 될 것입니다.

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> 
    ); 
    } 
} 

을이 예에서 경로 인 경우, 난 항상 난 그냥 테스트, '기타'라우터에 뭔가를 렌더링 그에 따라 메시지를 일치시키고 업데이트하십시오. 다른 경로가 일치하는지 여부는 절대로 바뀌지 않습니다.