본문으로 건너뛰기

라우트 간 검색 매개변수를 공유하는 방법

TanStack Router에서는 검색 매개변수가 부모 라우트에서 자동으로 상속됩니다. 부모 라우트가 검색 매개변수를 검증하면 자식 라우트는 자체 매개변수와 함께 Route.useSearch()를 통해 해당 매개변수에 접근할 수 있습니다.

매개변수 상속 작동 방식

TanStack Router는 부모 라우트의 검색 매개변수와 자식 라우트의 매개변수를 자동으로 병합합니다. 라우트 계층 구조를 통해 다음과 같이 처리됩니다.

  1. 부모 라우트validateSearch로 공유 매개변수를 검증합니다.
  2. 자식 라우트가 검증된 매개변수를 자동으로 상속합니다.
  3. **Route.useSearch()**가 로컬 매개변수와 상속된 매개변수를 모두 반환합니다.

루트 라우트를 통한 전역 매개변수

루트 라우트에서 매개변수를 검증해 애플리케이션 전체에서 공유합니다.

// routes/__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { z } from 'zod'

const globalSearchSchema = z.object({
theme: z.enum(['light', 'dark']).default('light'),
lang: z.enum(['en', 'es', 'fr']).default('en'),
debug: z.boolean().default(false),
})

export const Route = createRootRoute({
validateSearch: globalSearchSchema,
component: RootComponent,
})

function RootComponent() {
const { theme, lang, debug } = Route.useSearch()

return (
<div className={`app theme-${theme} lang-${lang}`}>
{debug && <DebugPanel />}
<Outlet />
</div>
)
}
// routes/products/index.tsx
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'

const productSearchSchema = z.object({
page: z.number().default(1),
category: z.string().default('all'),
})

export const Route = createFileRoute('/products/')({
validateSearch: productSearchSchema,
component: ProductsPage,
})

function ProductsPage() {
// Contains both local (page, category) AND inherited (theme, lang, debug) parameters
const search = Route.useSearch()

return (
<div>
<h1>Products (Theme: {search.theme})</h1>
<p>Page: {search.page}</p>
<p>Category: {search.category}</p>
</div>
)
}

레이아웃 라우트를 통한 섹션별 매개변수

레이아웃 라우트를 사용해 앱의 한 섹션 안에서 매개변수를 공유합니다.

// routes/_authenticated.tsx
import { createFileRoute, Outlet } from '@tanstack/react-router'
import { z } from 'zod'

const authSearchSchema = z.object({
impersonate: z.string().optional(),
sidebar: z.boolean().default(true),
notifications: z.boolean().default(true),
})

export const Route = createFileRoute('/_authenticated')({
validateSearch: authSearchSchema,
component: AuthenticatedLayout,
})

function AuthenticatedLayout() {
const search = Route.useSearch()

return (
<div className="authenticated-layout">
{search.sidebar && <Sidebar />}
<main className="main-content">
{search.notifications && <NotificationBar />}
<Outlet />
</main>
{search.impersonate && <ImpersonationBanner user={search.impersonate} />}
</div>
)
}
// routes/_authenticated/dashboard.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated/dashboard')({
component: DashboardPage,
})

function DashboardPage() {
// Contains inherited auth parameters (impersonate, sidebar, notifications)
const search = Route.useSearch()

return (
<div>
<h1>Dashboard</h1>
{search.impersonate && (
<Alert>Currently impersonating: {search.impersonate}</Alert>
)}
<DashboardContent />
</div>
)
}

일반적인 사용 사례

전역 애플리케이션 설정:

  • 테마, 언어, 시간대
  • 디버그 플래그, 기능 토글
  • 애널리틱스 추적(UTM 매개변수)

섹션별 상태:

  • 인증 컨텍스트(사용자 역할, 사용자 가장)
  • 레이아웃 환경설정(사이드바, 밀도)
  • 워크스페이스 또는 조직 컨텍스트

영구 UI 상태:

  • 모달 표시 여부, 드로어 상태
  • 필터 프리셋, 보기 모드
  • 접근성 환경설정

일반적인 문제

문제: 매개변수가 상속되지 않음

원인: 부모 라우트가 공유 매개변수를 검증하지 않습니다.

// ❌ Root route missing validateSearch
export const Route = createRootRoute({
component: RootComponent, // No validateSearch
})

// Child route can't access theme parameter
function ProductsPage() {
const search = Route.useSearch() // No theme available
}

해결 방법: 부모 라우트에 validateSearch를 추가합니다.

// ✅ Root route validates shared parameters
export const Route = createRootRoute({
validateSearch: globalSearchSchema,
component: RootComponent,
})

문제: 내비게이션 중 공유 매개변수가 사라짐

원인: 내비게이션 중 상속된 매개변수를 유지하지 않습니다.

// ❌ Navigation overwrites all search parameters
router.navigate({
to: '/products',
search: { page: 1 }, // Loses theme, lang, etc.
})

해결 방법: 함수 구문으로 기존 매개변수를 유지합니다.

// ✅ Preserve existing parameters
router.navigate({
to: '/products',
search: (prev) => ({ ...prev, page: 1 }),
})

문제: 상속된 매개변수에서 타입 오류 발생

원인: 자식 라우트 스키마가 상속된 매개변수를 고려하지 않습니다.

// ❌ TypeScript error: Property 'theme' doesn't exist
const search = Route.useSearch()
console.log(search.theme) // Type error

해결 방법: validateSearch를 사용하면 TypeScript가 상속된 타입을 자동으로 추론합니다. 추가 타입 지정은 필요하지 않으며 상속이 자동으로 작동합니다.

프로덕션 체크리스트

  • 명확한 소유권: 어떤 라우트가 어떤 공유 매개변수를 검증하는지 문서화합니다.
  • 충돌 방지: 라우트 수준마다 서로 다른 매개변수 이름을 사용합니다.
  • 내비게이션 중 유지: 함수 구문을 사용해 상속된 매개변수를 유지합니다.
  • 간결한 URL: 필수 공유 매개변수만 포함합니다.
  • 적절한 기본값: 모든 공유 매개변수에 대체값을 제공합니다.