React Router
React Router에 대한 자세한 소개는 React Router의 getting-started tutorial을 참고하세요.
// getting-started tutorial
} />
} />
} />
대부분의 간단한 예제로는 위와 같이 경로에 맞게 렌더링하게 될 컴포넌트를 설정하는 형태로 작성되게 됩니다. 전자증명서에서는 각 증명서에 맞는 경로가 존재하였고, 각 경로에 맞는 페이지 컴포넌트들이 존재하였습니다.
전자증명서에서 사용된 모듈 버전은 다음과 같습니다.
react : 17.0.2
react-router : 5.2.0
Route 개선이 필요했던 이유
이 글에서 사용된 예제코드는 이해를 돕기 위한 예시 코드로 실제 사용된 코드는 아닙니다.
// App.jsx
import 건강보험자격득실확인서 from './건강보험자격득실확인서';
import 코로나19예방접종증명서 from './코로나19예방접종증명서';
import 주민등록등본 from './주민등록등본';
import 주민등록초본 from './주민등록초본';
import 건강보험료납부확인서 from './건강보험료납부확인서';
import 운전경력증명서 from './운전경력증명서';
...
const App = () => {
...
return (
...
<건강보험자격득실확인서 />
<코로나19예방접종증명서 />
<주민등록등본 />
<건강보험자격득실확인서 />
<건강보험료납부확인서 />
<운전경력증명서 />
...
);
};
Route 개선
개선의 시작은 코드를 분리하는 것부터 시작하였고 페이지와 레이어 단위로 분리하여 각 경로에 맞는 Route를 설정하도록 수정하였습니다.
라우팅 정보 리스트화
// routes.jsx
import 건강보험자격득실확인서 from './건강보험자격득실확인서';
import 코로나19예방접종증명서 from './코로나19예방접종증명서';
...
const PAGE_LIST = [
{
path: '건강보험자격득실확인서',
children: <건강보험자격득실확인서 />,
},
{
path: '코로나19예방접종증명서',
children: <코로나19예방접종증명서 />,
},
...
];
// AppRoute.jsx
const AppRoute = () => {
...
return (
<>
{PAGE_LIST.map(({path, children}) => (
{children}
))}
>
);
};
위와 같은 형태로 라우팅 정보들을 리스트화하여 코드 정리를 하고 어느 정도 코드가 간소화되었지만 조금 더 코드 개선이 필요하다고 생각되었습니다.
이렇게 하나의 코드로 통합하는 것은 import를 통해 각자의 역할에 맞게 코드를 분할하여 작성할 수 있도록 도움을 주지만, 이러한 코드 통합은 코드양이 증가할수록 번들된 파일이 커지게 됩니다.
코드 분할이란?
Javascript로 작성된 코드들은 webpack, rollup과 같은 번들러를 통해 하나의 코드로 통합한 번들된 파일을 만들어 해당 파일을 로드하여 사용할 수 있습니다. 여기서 번들된 코드를 나누어 런타임에 필요로하지 않는 코드들은 지연 로딩하여 불러올 수 있습니다.
import 건강보험자격득실확인서 from './건강보험자격득실확인서';
import 코로나19예방접종증명서 from './코로나19예방접종증명서';
import 주민등록등본 from './주민등록등본';
import 주민등록초본 from './주민등록초본';
import 건강보험료납부확인서 from './건강보험료납부확인서';
import 운전경력증명서 from './운전경력증명서';
...
Next.js Routing
Next.js에서 제공하는 페이지 라우팅은 pages 폴더 하위 경로와 URL을 매칭시켜 URL 정보로 pages 폴더 하위 컴포넌트가 로드되도록 라우팅 처리를 별도의 코드 구성없이 지원합니다.

https://digitaldocs.kakao.com/건강보험료납부확인서
https://digitaldocs.kakao.com/건강보험자격득실확인서
https://digitaldocs.kakao.com/운전경력증명서
https://digitaldocs.kakao.com/주민등록등본
https://digitaldocs.kakao.com/주민등록초본
https://digitaldocs.kakao.com/코로나19예방접종증명서
import {useState, useEffect, createElement} from 'react';
const RouteComponent = ({path}) => {
const [component, setComponent] = useState(null);
useEffect(() => {
const importModule = async () => {
const {default: C} = await import(`pages/${(path)}`);
setComponent(() => C);
};
importModule();
}, [path]);
return (
<>{component ? createElement(component) : null}>
);
};
export default RouteComponent;
const PAGE_LIST = [
{
path: '건강보험자격득실확인서',
},
{
path: '코로나19예방접종증명서',
},
...
];
const AppRoute = () => {
...
return (
<>
{PAGE_LIST.map(({path}) => {
return (
);
})}
>
);
};
import {useState, useEffect} from 'react';
const pageImport = (path) => import(`pages${path}`);
const layerImport = (path) => import(`layer${path}`);
const useRouteComponent = (path, type) => {
const [component, setComponent] = useState(null);
useEffect(() => {
const importModule = async () => {
if (type === PAGES) {
const {default: Page} = await pageImport(path);
setComponent(() => Page);
}
if (type === LAYER) {
const {default: Layer} = await layerImport(path);
setComponent(() => Layer);
}
};
importModule();
}, [path]);
return {
component
};
};
export default useRouteComponent;
PAGE_LIST.map(({path}) => {
const isActive = matchPath(location.pathname, {path})?.isExact;
...
})
// import 건강보험자격득실확인서 from './건강보험자격득실확인서';
// import 코로나19예방접종증명서 from './코로나19예방접종증명서';
...
const PAGE_LIST = [
{
path: '건강보험자격득실확인서',
// children: <건강보험자격득실확인서 />,
},
{
path: '코로나19예방접종증명서',
// children: <코로나19예방접종증명서 />,
},
...
];
const PageRoute = ({path}) => {
const {component} = useRouteComponent(path);
return (
{component ? createElement(component) : null}
);
};
const AppRoute = () => {
...
return (
<>
{PAGE_LIST.map(({path}) => {
const isActive = matchPath(location.pathname, {path})?.isExact;
return isActive ? : <>>;
})}
>
);
};