Skip to main content

Command Palette

Search for a command to run...

React Router DOM을 Suspense와 같이 작성해야 하는 이유

React 프로젝트에서 React Router DOM으로 라우팅을 관리할 때 Suspense, lazy까지 활용해야 하는 이유 및 과정을 작성했습니다.

Published
2 min read
React Router DOM을 Suspense와 같이 작성해야 하는 이유

React Router DOM

React 프로젝트에서는 React Router DOM으로 페이지 라우팅을 관리할 수 있다.

공식문서에서는 Data API를 활용할 수 있는 createBrowserRouter를 통해 라우팅을 구성하는 예제를 보여준다.

  • RouteObject마다 렌더링할 컴포넌트를 명시할 수 있다.

    • 예제 프론트엔드에는 /home, /detail, /settings 주소가 존재한다.

    • 각 주소마다 Home, Detail, Settings 페이지 컴포넌트가 작성되어있다.

  • 하나의 라우팅에 여러 개의 하위 라우팅을 children 형태로 적용할 수 있다.

  • Home, Children 컴포넌트 모두 Layout 컴포넌트 내부에 배치될 수 있다.

const routes: RouteObject[] = [
  {
    path: "/",
    children: [
      {
        path: "/",
        element: <Layout />,
        children: [
          {
            path: "/home",
            element: <Home />,
          },
          {
            path: "/detail",
            element: <Detail />,
          },
        ],
      },
      {
        path: "/settings",
        element: <Setting />,
      },
    ],
  },
];

export default routes;

이슈

개발 도중 네트워크 요청이 예상보다 많이 발생한다는 이슈가 있어 확인 결과 Home 컴포넌트에서 Detail 컴포넌트 또한 렌더링되는 것을 확인할 수 있었다.

Detail 컴포넌트가 렌더링되면 컴포넌트 내부에 작성된 Hooks가 호출되면서 관련 네트워크 요청이 실행되는 것이었다.

각 라우팅에 걸려있는 컴포넌트마다 Suspense 컴포넌트를 적용해서 특정 페이지에 접속하면 해당하는 컴포넌트만 실행되도록 리팩토링 작업을 거쳤다.

우선 페이지 컴포넌트를 export default로 모듈을 내보낼 수 있어야 한다.

  • lazy에는 컴포넌트를 동적으로 불러오는 함수를 인자로 전달한다.

  • 동적 Import로 반환되는 컴포넌트는 Promise 형태이다.

  • 프론트엔드가 컴포넌트를 렌더링할 때 Promise가 완료될 때까지 대기한 다음 default 속성의 값을 리액트 컴포넌트로 렌더링하기 때문이다.

// export function Home()
export default function Home() {
  const location = useLocation();
  const { data, error, isLoading } = useHomeData();

  return (
    <div>
      <h1>Home page</h1>
    </div>
  );
}

각 컴포넌트를 React.lazy로 모듈을 불러오게 변경한다.

  • lazy는 컴포넌트가 첫번째로 렌더링될 때까지 컴포넌트 실행을 연기시킨다.

  • 각 페이지 컴포넌트를 Suspense의 하위 컴포넌트 형태로 작성한다.

    • Suspense는 컴포넌트가 렌더링 완료될 때까지 fallback으로 지정된 컴포넌트를 보여줄 수 있다.
const Home = lazy(() => import("./pages/Home"));

const routes: RouteObject[] = [
  {
    path: "/",
    children: [
      {
        path: "/",
        element: <Layout />,
        children: [
          {
            path: "/home",
            element: (
              <Suspense>
                <Home />
              </Suspense>
            ),
          },
          {
            path: "/detail",
            element: (
              <Suspense>
                <Detail />
              </Suspense>
            ),
          },
        ],
      },
      {
        path: "/settings",
        element: (
          <Suspense>
            <Setting />
          </Suspense>
        ),
      },
    ],
  },
];

export default routes;

결과

페이지를 이동할 때마다 각 페이지에 해당하는 컴포넌트가 필요한 네트워크 요청만 실행하기 때문에 네트워크 요청 수를 절약할 수 있었다.

추가적인 컴포넌트를 작성해야 하는 것도 알 수 있었다.

  • lazy 함수 호출하는 과정에서 프로미스가 실패할 것을 대비해서 ErrorBoundary 역할의 컴포넌트

  • lazy 함수 호출 후 컴포넌트를 렌더링하는 동안 대신 렌더링할 fallback 역할의 컴포넌트

More from this blog

AI 에이전트에서 작업 맥락을 관리하기 위해 사용한 방법

AI 에이전트의 불편함 Codex CLI와 같은 AI 코딩 에이전트를 통해서 프로젝트 개발 속도를 높일 수 있다. 그리고 혼자 작업했을 때는 놓칠 수 있는 부분도 발생할 수 있는데 AI 에이전트를 통해 보완할 수 있었다. 컴포넌트에 대해서 접근성 태그 작성 API 호출하는 비동기 코드 작성할 때 에러 처리 그리고 AI 에이전트를 잘 활용하면 불가능하

Mar 8, 202610 min read

지시사항을 분할하여 Codex로 효율적인 작업하기

이슈 Codex와 같은 AI 기반 코드 에이전트는 출력 토큰의 수가 제한되어 있다. 그래서 다양한 작업을 하나의 프롬프트에 전부 몰아서 작성하면 원하는 결과가 나오지 않을 수 있다. Codex와 같은 LLM 기반 서비스는 출력 토큰 수를 초과하게 되면 일부 단계가 누락되거나 특정 요소를 과하게 요약할 수 있고 이는 전체적인 답변 퀄리티를 낮출 수 있기 때문이다. 그래서 다양한 AI 공식문서는 특정 작업을 더 작은 단위로 분할하는 방식을 강조한다...

Nov 3, 20255 min read

Key를 활용하여 컴포넌트 상태를 초기화하기

개요 컴포넌트의 상태가 업데이트되어도 컴포넌트 내부에 배치된 컴포넌트의 상태는 그대로 유지되는 경우가 있었다. 예전에는 Props 전달 및 내부에서 useEffect를 통해서 상태를 초기 상태로 업데이트하도록 했는데 useEffect를 남용하게 되면 상태 변화 추적이 어려워지는 문제가 있었다. 그런데 useEffect 외에도 Key를 통해서 컴포넌트 상태를 초기화할 수 있다는 사실을 알게 되었다. 리스트 렌더링 React 프론트엔드에서 목록 형...

Sep 21, 20253 min read

내가 AGENTS.md를 작성하는 방법

Codex CLI 요즘 프로젝트 개발에 Codex CLI를 활용하는 이유는 다음과 같다. 특정 프로젝트를 작업할 때 Claude Code는 종종 사용량을 초과한 것과 다르게 Codex CLI는 ChatGPT Plus 요금제만으로도 토큰 사용량 초과 걱정 없이 충분하게 활용할 수 있었다. 타 CLI 기반 AI 개발 도구에 비해서 요구사항을 더 정확하게 구현하고 꼭 필요한 작업만 진행하기 때문에 코드를 검토하는 시간을 줄일 수 있다. 반복적인 코드...

Sep 21, 20254 min read
N

Nowon Lee

22 posts