본문으로 바로가기
TaeyoungKim.dev

React Router 중첩 경로가 빈 화면일 때: children과 Outlet 확인

웹작성 약 3분 읽기TaeyoungKim
LinkedInX

/settings/profile로 이동했는데 공통 메뉴만 보이고 프로필 화면은 비어 있다. 자식 라우트를 children에 넣었다면, 부모 컴포넌트에는 그 자식이 들어갈 자리가 필요하다. React Router에서 그 자리가 <Outlet />이다. URL이 맞는지와 화면에 그릴 위치가 있는지를 따로 점검하자.

children은 경로를, Outlet은 화면 자리를 정한다

도식의 경로 트리는 어떤 자식을 선택할지 정하고, 부모 화면의 <Outlet />은 그 자식을 실제로 끼울 자리를 정한다. 자식 경로가 일치해도 이 자리가 없으면 부모 레이아웃만 보인다.

다음 예제는 React Router Data Mode의 작은 라우트 트리다. 부모 경로 /settings에 공통 레이아웃을 두고, 자식 경로 profile에 프로필 내용을 둔다.

jsx
import { createBrowserRouter, Outlet } from 'react-router';
import { RouterProvider } from 'react-router/dom';

function SettingsLayout() {
  return (
    <main>
      <h1>설정</h1>
      <nav>설정 메뉴</nav>
      <Outlet />
    </main>
  );
}

function Profile() {
  return <p>프로필 설정 화면</p>;
}

const router = createBrowserRouter([
  {
    path: '/settings',
    element: <SettingsLayout />,
    children: [{ path: 'profile', element: <Profile /> }],
  },
]);

export default function App() {
  return <RouterProvider router={router} />;
}

/settings/profile에서는 부모 레이아웃이 먼저 보이고, <Outlet /> 위치에 Profile이 그려진다. children을 설정해도 부모에서 <Outlet />을 지우면 자식 화면을 표시할 자리가 없다. 반대로 <Outlet />만 있고 해당 URL에 맞는 자식 경로가 없다면 자식 내용이 비어 있는 것이 자연스럽다. 정확한 렌더링 계약은 React Router의 Outlet 설명에서 확인할 수 있다.

URL이 맞는데 화면이 비면 무엇부터 볼까?

첫째, 현재 URL이 부모 경로와 자식 경로를 합친 /settings/profile인지 확인한다. 둘째, children 배열에서 profile이 부모의 자식인지 본다. 셋째, 부모가 실제 렌더링하는 컴포넌트에 <Outlet />이 있는지 확인한다. 공통 레이아웃 코드만 보지 말고 조건부 렌더링 때문에 Outlet 자체가 사라지는지도 살펴본다.

예제의 자식 경로는 앞에 /를 붙이지 않은 상대 경로다. 팀 코드에서 절대 경로와 상대 경로를 섞어 쓰면 의도와 다른 라우트가 될 수 있으므로, 최종 URL을 기준으로 테스트한다. /settings만 열었을 때 기본 화면이 필요하다면 별도 인덱스 자식 라우트를 설계해야 한다. 빈 화면이 언제나 오류인 것은 아니다.

레이아웃을 나눌 때의 운영 판단

부모 레이아웃은 여러 자식 화면이 공유하는 제목·메뉴·경계에 적합하다. 자식 화면에만 필요한 데이터 로딩이나 오류 처리를 모두 부모에 몰아넣으면 작은 페이지 변경에도 공통 레이아웃이 복잡해진다. 먼저 어느 요소를 모든 자식이 공유하는지 정하고, 나머지는 자식 라우트에 둔다.

브라우저에서 /settings/profile로 직접 접근하는 테스트와 내부 링크로 이동하는 테스트를 모두 한다. 직접 접근만 실패한다면 Outlet 문제가 아니라 서버의 SPA 경로 처리일 수 있다. 같은 화면의 실패라도 라우터 매칭, 화면 자리, 서버 응답을 나눠 보면 원인을 더 빨리 찾는다.

핵심 요약: 중첩 경로에는 렌더링 자리도 필요하다

children이 자식 경로를 정의하고 <Outlet />이 부모 화면에서 자식이 들어갈 위치를 만든다. URL은 맞는데 부모만 보인다면 자식 경로 매칭과 Outlet 렌더링을 차례로 확인하자.

작성자

TaeyoungKim

기초 개념을 구현과 검증, 실제 운영 판단까지 연결해 기록합니다.

#React Router#Outlet#중첩 라우팅#children#createBrowserRouter

함께 읽으면 좋은 글