JoungSik/React Router Dom 여러 개의 Layout 사용하기

Created Fri, 19 Nov 2021 23:59:59 +0900 Modified Sat, 31 Dec 2022 01:31:35 +0900
521 Words

React Router Dom 여러 개의 Layout 사용하기

고민하다보면 다른 방법도 있지만 현재 업무 중에 적용한 내용을 작성하려고 합니다.

상황은 이렇습니다.

/a 와 /b 각각의 하위 라우트에서 사용되는 Layout 이 다르게 적용 되어야 합니다.

각각 AHeader 와 BHeader 가 적용되어야 하는 상황입니다.

설치

yarn create react-app sample --template typescript

라우트 관리를 해주는 라이브러리를 설치합니다.

최근 6.x로 버전이 올라서 네이밍이 바뀌고 사용법이 바뀐게 있어 기존 버전을 설치하도록 하겠습니다.

yarn add react-router-dom@^5.3.0
yarn add -D @types/react-router-dom@^5.3.0

자주 쓰는 라우트 설정 방식으로 폴더 구조를 생성합니다.

mkdir src/routes
vi src/routes/index.tsx
vi src/routes/data.ts

mkdir src/pages
vi src/pages/a.tsx
vi src/pages/b.tsx
vi src/pages/home.tsx

src/routes/data.ts

import React from 'react';

import Home from '../pages/home';
import A from '../pages/a';
import B from '../pages/b';

export interface RouteProps {
    path: string,
    component: React.FC
}

export const ARoutes: Array<RouteProps> = [
    {
        path: '/',
        component: A,
    }
];

export const BRoutes: Array<RouteProps> = [
    {
        path: '/',
        component: B,
    }
];

export const Routes: Array<RouteProps> = [
    {
        path: '/',
        component: Home,
    }
]

src/routes/index.tsx

import React from 'react';
import { BrowserRouter as Router, Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Routes, ARoutes, BRoutes } from './data';
import AHeader from '../components/a_header';
import BHeader from '../components/b_header';

const aRoutes = ({ match }: RouteComponentProps) => {
  return (
    <>
      <AHeader />
      <Switch>
        {
          ARoutes.map(route => <Route exact
                                      key={route.path} path={match.url + route.path} component={route.component} />)
        }
      </Switch>
    </>
  )
};

const bRoutes = ({ match }: RouteComponentProps) => {
  return (
    <>
      <BHeader />
      <Switch>
        {
          BRoutes.map(route => <Route exact
                                      key={route.path} path={match.url + route.path} component={route.component} />)
        }
      </Switch>
    </>
  )
};

const Routers = () => {
  return (
    <Router>
      <Switch>
        <Route path={'/a'} component={aRoutes} />
        <Route path={'/b'} component={bRoutes} />
        {
          Routes.map(route => <Route exact key={route.path} path={route.path} component={route.component} />)
        }
      </Switch>
    </Router>
  )
}

export default Routers;

각 pages 와 headers 는 이름만 다르고 형태는 다 같습니다.

src/pages/{name}.tsx

import React from 'react';

const {name} = () => {
  return (
    <div>
      <h1>{name}</h1>
    </div>
  )
};

export default {name};

src/components/{name}_header.tsx

import React from 'react';

const {name}Header = () => {
  return (
    <div>
      <h1>{name} Header</h1>
    </div>
  )
};

export default AHeader;

src/app.tsx 파일도 수정합니다.

import React from 'react';
import Routers from './routes';

function App() {
  return <Routers />;
}

export default App;

1

2

다음처럼 동작하게 됩니다.