폴더 트리가 그대로 렌더 트리가 돼
각 라우트 구간은 자기 layout.tsx를 가질 수 있고, 자식 레이아웃은 부모 레이아웃 안에 자동으로 들어가. 따로 import해서 껍데기를 조립하지 않아도 폴더 구조가 화면의 감싸기 순서를 결정해.
app/layout.tsx → 모든 화면을 감쌈
app/dashboard/layout.tsx → /dashboard/*를 감쌈
app/dashboard/settings/page.tsx → 두 레이아웃 안에 표시됨
주소가 바뀌어도 같은 조상은 유지돼
/dashboard/settings에서 /dashboard/billing으로 이동하면 두 페이지가 공유하는 루트와 대시보드 레이아웃은 그대로 있고 페이지 부분만 바뀌어. 반대로 /marketing/pricing으로 가면 대시보드 레이아웃은 트리에서 빠지고 마케팅 쪽 레이아웃이 들어와. 어느 상태가 살아남는지는 URL 전체가 아니라 두 라우트가 공유하는 조상이 결정해.
초기 선택은 layout.tsx야
대부분의 공통 UI에는 레이아웃이 맞아. 이동할 때마다 상태를 새로 만들거나 진입·퇴장 애니메이션을 처음부터 재생해야 할 때만 template.tsx를 써. 두 파일은 같은 props를 받지만 템플릿은 내비게이션마다 다시 마운트된다는 차이가 있어.
수명부터 정하고 자리를 골라
컴포넌트가 오래 살아야 해서 레이아웃에 놓는 게 아니라, 그 구간 전체가 공유해야 하는 책임이라서 놓는 거야. 공유 범위와 초기화 시점을 먼저 말로 적으면 레이아웃이 비대해지는 일을 막을 수 있어.
두 주소 사이를 이동할 때 어떤 조상이 유지되어야 하는지 렌더 트리로 그려 봐. 대시보드 안의 탭 상태는 대시보드 레이아웃에, 앱 전체 테마는 루트에 두는 식이야. 상태 초기화 버그는 컴포넌트 코드보다 잘못 고른 수명 경계에서 더 자주 생겨. template.tsx로 강제 재마운트하면 오래된 상태 문제를 빨리 숨길 수 있지만, 입력 중인 값과 네트워크 캐시도 함께 버릴 수 있어. 먼저 상태가 잘못된 조상에 있는지 확인하고, 화면 전체가 새 인스턴스여야 한다는 제품 이유가 있을 때만 템플릿을 골라.
/dashboard/settings와 /dashboard/billing, 그리고 다른 최상위 구역 사이를 이동하며 mount 로그를 남겨. 조상 레이아웃과 template의 mount 횟수를 비교하고, 애니메이션 때문에 template을 썼을 때 사용자가 입력하던 상태까지 사라지는지 확인해 선택의 대가를 보여.