Tanstack Router 1

한상욱·2024년 3월 11일

tanstack router

목록 보기
1/3

Route Tree & Nesting

Tanstack Router는 라우트 트리를 만들 때 두가지 방식을 지원한다.

  • 파일 기반 라우팅
  • 코드 기반 라우팅

파일 기반 라우팅을 사용하기를 바란다. 더 적은 코드로 같거나 더 나을 결과를 얻어낸다.

Route Trees

만약 /blog/posts/123이라는 URL이 주어졌다고 하자. 그러면 아래와 같은 구조의 Nested된 URL이다.

  • /blog
    • posts
      • $postId

그러면 컴포넌트 렌더 트리는 다음과 같이 생겼다.

<Blog>
  <Posts>
    <Post postId="123" />
  </Posts>
</Blog>

Tanstack Query는 이런 계층형 라우터를 라우트 트리라고 부른다.

Routing Concepts

Tanstack Router로 아래 라우터를 모두 표현할 수 있다.

Root Route

가장 최상단 라우터로 모든 라우터를 포함하는 라우터이다.

  • path 없음
  • 항상 match 되는 라우터
  • 여기에 존재하는 컴포넌트는 항상 렌더링

path가 없더라도 root Route는 다른 라우터의 기능을 모두 동일하게 수행할 수 있다.

다음은 Root Route 만드는 방법이다.

// src/routes/__roots.tsx

import { createRootRoute } from '@tanstack/react-router';

export const Route = createRootRoute();

Anatoby of a Route

Root Route를 제외한 모든 라우터는 FileRoute로 구성된다.

import { createFileRoute } from '@tanstack/react-router';
import { PostsComponent } from '@/src/components/PostComponent';

export const Route = createFileRoute('/posts')({
  component: PostsComponent,
});

createFileRoute 경로 매개변수

개발자가 createFileRoute에 path를 넘겨주면 vite plugin이나 Router CLI가 자동으로 라우터 경로를 만들어준다.

Static Routes

/user, /about과 같은 꼴의 정적 페이지를 만들 때 사용한다. 진짜 쉽다.

// src/routes/about.tsx

import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/about')({
  component: AboutComponent,
})

function AboutComponent() {
  return <div>About</div>
}

Index Routes

Parent Route에는 정확히 맞지만 child Route에는 맞는 것이 없는 경우 사용하는 Route이다. 파일 이름 끝에 index.tsx라고 붙여준다.

아래와 같은 경우 페이지 URL은 /posts이다.

// src/routes/post.index.tsx

import { createFileRoute } from '@tanstack/react-router';

export const Route = createFileRoute('/posts/')({
  component: PostsIndexComponent,
});

function PostsIndexComponent() {
  return <div>Please select a post!</div>
}

Dynamic Route Segments

$를 붙여서 반들고 params 객체에서 필요한 slug를 뽑아 먹는 형태이다.

아래와 같은 경우는 /posts/123과 같은 형태의 URL 페이지를 만들 수 있다.

// src/routes/posts/posts.$postId.tsx

import { createFileRoute } from '@tanstack/react-router';

export const Route = createFileRoute('/posts/$postId')({
  // In a loader
  loader: ({ params }) => fetchPost(params.postId),
  // Or in a component
  component: PostComponent,
});

function PostComponent() {
  const { postId } = Route.useParams()
  return <div>Post ID: {postId}</div>
}

신기한건 createFileroute에 넣어준 /posts/$postId에서 paramspostId라는 필드를 $postId로부터 파싱하여 자동으로 생성해준다. 개꿀이다.

Splat/Catch-All Routes

$표시를 "splat"이라고 부른다. 만약 /files/documents/hello-world라면 params_splatdocuments/hello-world가 된다.

{
  '_splat': 'documents/hello-world'
}

Pathless Routes

파일 라우터는 prefix가 _로 시작하는 경우 Pathless 라우터라고 한다. Pathhless 라우터는 child Route에게 자신의 path를 부여하지 않고 자신의 컴포넌트나 비즈니스 로직을 부여할 수 있다.

만약 _layout이라는 라우터가 있고 이걸로 layout-a와 layout-b를 감싼다면 /layout-a과 layout-b만으로 child routes를 부를 수 있다.

// LayoutA.tsx

<Layout>
  <LayoutA />
</Layout>

// LayoutB.tsx
<Layout>
  <LayoutB />
</Layout>

// src/_layout.tsx
import { createFileRoute } from '@tanstack/react-router';

export const Route = createFileRoute('/_layout')({
  component: LayoutComponent,
});

function LayoutComponent() {
  return (
    <div>
      <h1>Layout</h1>
      <Outlet />
    </div>
  )
}

이해가 잘 가지 않는 나를 위해 영상 하나 넣어둔다.
https://www.youtube.com/watch?v=cTV6zS57Fdg

Non-Nested Routes

Non-Nested Routes는 parent 파일 route 이름에 _를 붙이면 된다. 이거 부모 라우터 형태는 유지하면서 Nested가 아닌 라우터 만드는데 유용하다.

path 매칭에서는 _는 무시된다. 그래서 /posts/posts_는 같은 path이다. 하지만 컴폰넌트 트리에서는 이 두 가지를 _를 붙여서 구분한다. 따라서 /posts/posts_는 다른 라우터로 구분된다.

  • /posts_/$postId/edit
  • /posts
    • $postId

이 경우는 /posts/posts_/$postId/edit은 동등한 레벨의 라우터이다. /posts/posts/$postId/edit에 부모-자식 관계는 아니다.

// `posts_.$postId.edit.tsx`
<EditPost postId={postId} />

// `posts.$postId.tsx`
<Posts>
  <Post postId={postId} />
</Posts>

여기서는 EditPostPost의 자식이 아니라서 Post로 쌓여 있지 않다.

404/NotFoundRoute

없는 페이지 띄우는 라우터이다.

NotFoundRoute가 나타나는 조건은 다음과 같다.

  • 들어온 URL이 가능한 라우터에 없는 경우
  • dynamic 라우터나 splat 라우터가 맞는게 없는 경우
  • Parent Route는 맞는데 Parent Route에 index가 없는 경우
  • notFoundRoute가 라우터에 존재하는 경우

간단히 아래 세 가지 경우로 종합된다.

  • no path
  • no id
  • 파서를 못하거나 유효하지 않은 paramater인 경우

근데, 얘네들도 똑같이 라우터의 일을 수행할 수 있다.

profile
그냥 뛰는 사람

0개의 댓글