Development Tip

레이아웃 페이지 또는 페이지 당 여러 구성 요소와 함께 React-Router 사용

yourdevel 2021. 1. 6. 20:29
반응형

레이아웃 페이지 또는 페이지 당 여러 구성 요소와 함께 React-Router 사용


기존 프로젝트에 반응 라우터를 추가하고 있습니다.

현재 모델은 하위 탐색을위한 탐색 구성 요소와 기본 구성 요소를 포함하는 루트 구성 요소로 전달됩니다.

내가 찾은 반응 라우터의 예에는 하나의 하위 구성 요소 만 있습니다. 둘 다에서 레이아웃 코드를 반복하지 않고 여러 하위 구성 요소를 변경하는 가장 좋은 방법은 무엇입니까?


내가 올바르게 이해했다면이를 달성하기 위해 Route. 다음과 같이 사용할 수 있습니다.

// think of it outside the context of the router, if you had pluggable
// portions of your `render`, you might do it like this
<App children={{main: <Users/>, sidebar: <UsersSidebar/>}}/>

// So with the router it looks like this:
const routes = (
  <Route component={App}>
    <Route path="groups" components={{main: Groups, sidebar: GroupsSidebar}}/>
    <Route path="users" components={{main: Users, sidebar: UsersSidebar}}>
      <Route path="users/:userId" component={Profile}/>
    </Route>
  </Route>
)

class App extends React.Component {
  render () {
    const { main, sidebar } = this.props;
    return (
      <div>
        <div className="Main">
          {main}
        </div>
        <div className="Sidebar">
          {sidebar}
        </div>
      </div>
    )
  }
}

class Users extends React.Component {
  render () {
    return (
      <div>
        {/* if at "/users/123" `children` will be <Profile> */}
        {/* UsersSidebar will also get <Profile> as this.props.children,
            so its a little weird, but you can decide which one wants
            to continue with the nesting */}
        {this.props.children}
      </div>
    )
  }
}

또한 더 많은 도움이 될 사이드 바 예제 앱을 확인하십시오 .

편집 : @Luiz의 의견에 따라 :

최신 버전의 라우터 (v3)에서 컴포넌트는 props 객체의 루트에 있습니다.

그래서:

const { main, sidebar } = this.props.children;

된다 :

const { main, sidebar } = this.props;

편집 : react-router v4에서 다음과 같이 수행 할 수 있습니다 ( 새 문서에 제공된 예제에 따라 ).

import React from 'react'
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom'

// Each logical "route" has two components, one for
// the sidebar and one for the main area. We want to
// render both of them in different places when the
// path matches the current URL.
const routes = [
  { path: '/',
    exact: true,
    sidebar: () => <div>home!</div>,
    main: () => <h2>Home</h2>
  },
  { path: '/bubblegum',
    sidebar: () => <div>bubblegum!</div>,
    main: () => <h2>Bubblegum</h2>
  },
  { path: '/shoelaces',
    sidebar: () => <div>shoelaces!</div>,
    main: () => <h2>Shoelaces</h2>
  }
]

const SidebarExample = () => (
  <Router>
    <div style={{ display: 'flex' }}>
      <div style={{
        padding: '10px',
        width: '40%',
        background: '#f0f0f0'
      }}>
        <ul style={{ listStyleType: 'none', padding: 0 }}>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/bubblegum">Bubblegum</Link></li>
          <li><Link to="/shoelaces">Shoelaces</Link></li>
        </ul>

        {routes.map((route, index) => (
          // You can render a <Route> in as many places
          // as you want in your app. It will render along
          // with any other <Route>s that also match the URL.
          // So, a sidebar or breadcrumbs or anything else
          // that requires you to render multiple things
          // in multiple places at the same URL is nothing
          // more than multiple <Route>s.
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            component={route.sidebar}
          />
        ))}
      </div>

      <div style={{ flex: 1, padding: '10px' }}>
        {routes.map((route, index) => (
          // Render more <Route>s with the same paths as
          // above, but different components this time.
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            component={route.main}
          />
        ))}
      </div>
    </div>
  </Router>
)

export default SidebarExample

https://reacttraining.com/react-router/ 에서 새로운 React Router v4 문서를 확인하십시오.


구성 요소는 JSX를 반환하는 함수일 수 있습니다.

  <Route>
    <Route path="/" component={App}>
      <IndexRoute component={Home} />
      <Route path="Invite" component={()=>(<div><Home/><Invite/></div>)} />
    </Route>
  </Route>

2019 +

이를 수행하고 악의적 인 재 렌더링을 방지하는 간단하고 깨끗한 방법은 다음과 같습니다 (react 라우터 v5에서 테스트되었으며 react router v4에서 확인해야 함).

       <Switch>
         <Route exact path={["/route1/:id/:token", "/"]}>
          <Layout1>
            <Route path="/route1/:id/:token" component={SetPassword} />
            <Route exact path="/" component={SignIn} />
          </Layout1>
        </Route>
        <Route path={["/route2"]}>
          <Layout2>
            <Route path="/route2" component={Home} />
          </Layout2>
        </Route>
      </Switch>

다음과 같이 리팩토링 할 수 있습니다.

const routes = [
  {
    layout:Layout1,
    subRoutes:[
      {
        path:"/route1/:id/:token",
        component:SetPassword
      },
      {
        exact:true,
        path:"/",
        component:SignIn
      },
    ]
  },
  {
    layout:Layout2,
    subRoutes:[
      {
        path:"/route2",
        component:Home
      },
    ]
  }
];

와:

      <Switch>
        {routes.map((route,i)=>
          <Route key={i} exact={route.subRoutes.some(r=>r.exact)} path={route.subRoutes.map(r=>r.path)}>
            <route.layout>
              {route.subRoutes.map((subRoute,i)=>
                <Route key={i} {...subRoute} />
              )}
            </route.layout>
          </Route>
        )}
      </Switch>

참조 URL : https://stackoverflow.com/questions/33062830/using-react-router-with-a-layout-page-or-multiple-components-per-page

반응형