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;
다음처럼 동작하게 됩니다.