LearnApplyShare

[React] `pages` 폴더 경로를 이용한 동적 라우팅

December 18, 2020 - [react, routing, lazy, Suspense]

React 를 이용한 SPA 웹프로젝트를 개발한다고 할 때 react-router 를 이용한 라우팅은 웹 개발시 거의 필수적인 요소라고 해도 과언이 아닐 것입니다.

그리고 프로젝트가 점차 커지고 라우팅 패스가 하나 둘씩 많아 지게 되면, 자연스럽게 클라이언트 라우팅만을 담당하는 별도 컴포넌트 (가칭, Routes.js ) 를 생성하여 관리하게 될 것입니다.

그렇다면 라우팅을 담당하는 컴포넌트는 아마도 아래와 같은 모습을 하고 있겠죠?

Routes.js

import React from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Signin from "./pages/signin";
import Signup from "./pages/signup";
import Main from "./pages/index";
import NotFound from "./pages/NotFound";

export default function Routes() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/" component={Main} />
        <Route exact path="/signin" component={Signin} />
        <Route exact path="/signup" component={Signup} />
        // ... 이 아래로 10여 개의 라우팅 패스가 추가로 정의되어 있다고 상상해 봅시다. 😰
        <Route path="/" component={NotFound} />
      </Switch>
    </BrowserRouter>
  );
}

이러한 라우팅 설정은 라우팅해야 할 path 가 몇개 되지 않을 때에는 불편함이 없지만, 그 수가 많아 지기 시작하면 금방 짜증이 밀려오게 됩니다.

라우팅 패스가 하나 추가될 때마다 매번 import 문을 추가해야 하고 또 라우팅 설정도 하나씩 추가해야 하니까요.

혹시 현재 이런 불편함을 느끼고 있으시지는 않나요?

그렇다면 잘 오셨습니다.🙂


우리를 구원해 줄 lazy 와 Suspense

리액트 컴포넌트의 동적 로딩을 지원하기 위한 API 로서 React.lazy 와 React.Suspense 가 있다는 것을 아시나요? 이를 이용하면 pages 폴더의 파일 경로에 따라 그대로 라우팅이 되도록 구성하는 것이 가능합니다.

아래와 같이 말이죠.

DynamicRoutes.js

import React, { Suspense, lazy } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";

export default function DynamicRoutes() {
  return (
    <BrowserRouter>
      <Switch>
        <Route
          path="/"
          render={({ history, location, match }) => {
            const Page = lazy(() =>
              import("./pages" + location.pathname).catch((e) => {
                if (/not find module/.test(e.message)) {
                  return import("./pages/NotFound.js");
                }
                if (/Loading chunk \d+ failed/.test(e.message)) {
                  window.location.reload();
                  return;
                }
                throw e;
              })
            );
            return (
              <Suspense fallback={<div>Loading..</div>}>
                <Page />
              </Suspense>
            );
          }}
        />
      </Switch>
    </BrowserRouter>
  );
}

이렇게 동적 라우팅을 이용하면 더 이상 라우팅 패스가 추가될 때마다 라우팅 설정을 수정할 필요가 없습니다. pages 폴더 구조 자체가 바로 라우팅 설정이 되는 것이죠.

사실 이와 같은 방식은 Nextjs 에서 기본적으로 제공하는 라우팅 기능과 동일합니다. Nextjs 의 라우팅방식을 SPA에서도 동일하게 적용한 사례가 되겠지요.

혹시 누군가에게 작은 도움이 되기를 바라는 마음으로 정리해 보았습니다. 🙏


코드 데모