Tanstack Router 사용하기 01

송우든·2024년 7월 24일
2

React

목록 보기
23/23
post-thumbnail

Tanstack Router

Tanstack Router는 Typescript의 타입 시스템을 활용하여 라우팅을 관리하며 타입 안전성을 보장하는 것을 목표로 설계되었다. 즉, 개발자가 런타임 오류를 사전에 방지하고 코드를 더욱 안정적으로 유지할 수 있게 한다.


Code Splitting(코드 분할)

Tanstack Router는 Code Splitting을 통해 애플리케이션 성능 최적화를 위한 강력한 기능을 제공한다. Tanstack Router에서는 크게 두 가지로 경로 설정을 구분하다.

Critical Route Configuration : 현재 경로를 렌더링 및 초기 페이지 로드 시 필요한 코드를 포함한다. (스크립트, 스타일, 로더 등)
Non-Critical/Lazy Route Configuration : 필요할 때 로드할 수 있는 코드를 포함한다. (라우트 컴포넌트, 에러 컴포넌트 등)

위와 같이 두 가지 경로 설정을 구분하여 동작함으로써 초기 로딩 시 필요한 리소스만 먼저 로드하여 페이지 성능을 개선하고, 나머지는 필요할 때 동적으로 로드하여 사용자 경험을 최적화할 수 있다.

또한, Tanstack Router는 파일 기반의 라우팅 시스템을 지원하여 코드를 간편하게 분리할 수 있다. .lazy.tsx를 통해 지연 로드 컴포넌트를 쉽게 정의하고 디렉터리로 경로 파일을 캡슐화하여 관리할 수 있다.

추가적으로 로더는 필요에 따라 비동기적으로 로드되고 실행될 수 있기 때문에 로더를 가져오고 실행하는 과정까지 기다려야하는 추가적인 비용이 발생한다. 이로 인해 로더 또한, Critical Route Configuration로 분류된다.

#How does TanStack Router split code?


lazy.tsx 파일

Non-Critical/Lazy Route Configuration로 분류되는 코드 파일은 filename.lazy.tsx과 같이 생성한다. createLazyFileRoute를 사용하여 간단하게 구현할 수 있다. (__root.tsx 라우트 파일은 현재 경로와 관계없이 항상 렌더링 되기 때문에 코드 분할을 지원하지 않는다.)

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

export const Route = createLazyFileRoute('/')({
  component: () => <div>Hello!</div>
})


// 아래 코드는 Code-Based Splitting를 사용하는 방법이다.
const postsRoute = createRoute({
  getParent: () => rootRoute,
  path: '/posts',
}).lazy(() => import('./posts.lazy').then((d) => d.Route))

createLazyFileRoute에서 지원하는 옵션은 아래와 같다.

구분내용
component- 렌더링시 사용되는 컴포넌트를 정의한다. 
errorComponent - 라우트 로딩 중 오류가 발생했을 때 렌더링할 컴포넌트를 정의한다. 
pendingComponent- 라우트가 로딩 중일 때 렌더링할 컴포넌트를 정의한다. 
notFoundComponent- 404 / 잘못된 경로를 탐색할 때 렌더링할 컴포넌트를 정의한다. 

Route Tree(라우트 트리)

Tanstack RouterRoute Tree를 생성할 때, 아래 두 가지 방식을 지원한다.

(Tanstack Router는 파일 기반 라우팅을 권장한다. 파일 기반 라우팅은 더 적은 코드로 동일하거나 더 나은 결과를 얻을 수 있다. 또한, 대부분의 공식 문서가 파일 기반 라우팅을 기준으로 작성되었다.)

  • File-Based Routing
  • Code-Based Routing

Tanstack Router는 중첩 라우팅을 설정하기 위해 라우팅 계층구조라 불리는 Route Tree를 사용한다. (이를 통해 매칭되는 라우터 조직화 및 컴포넌트 트리로 구성한다.) Route Tree는 여러 다양한 방법으로 정의하여 사용할 수 있다.

Flat Routes- 동일 수준의 중첩을 사용한다. - 구조가 단순하고 이해하기 쉽다.(소규모 애플리케이션에 적합)
Directory Routes - 계층적으로 중첩된 라우트를 나타내는 방식이다. - 관련있는 라우터를 조직화(묶음)하거나 깊게 중첩된 라우트 파일 이름 길이를 단순화시킬 수 있다.
Mixed Flat and Directory Routes- 중첩된 라우트를 표현하면서 단일 배열의 단순성을 유지할 수 있다.
Code-Based Routes- 코드 내에서 동적으로 라우트를 정의하는 방식이다.
Case-Sensitivity - 경로의 대소문자 구분을 설정할 수 있는 기능이다.

:D Route Tree(라우트 트리)

Tanstack RouterRoute Tree를 생성할 때, 아래 두 가지 방식을 지원한다.

(Tanstack Router는 파일 기반 라우팅을 권장한다. 파일 기반 라우팅은 더 적은 코드로 동일하거나 더 나은 결과를 얻을 수 있다. 또한, 대부분의 공식 문서가 파일 기반 라우팅을 기준으로 작성되었다.)

  • File-Based Routing
  • Code-Based Routing

Tanstack Router는 중첩 라우팅을 설정하기 위해 라우팅 계층구조라 불리는 Route Tree를 사용한다. (이를 통해 매칭되는 라우터 조직화 및 컴포넌트 트리로 구성한다.) Route Tree는 여러 다양한 방법으로 정의하여 사용할 수 있다.

종류내용
Flat Routes- 동일 수준의 중첩을 사용한다. - 구조가 단순하고 이해하기 쉽다.(소규모 애플리케이션에 적합)
Directory Routes - 계층적으로 중첩된 라우트를 나타내는 방식이다. - 관련있는 라우터를 조직화(묶음)하거나 깊게 중첩된 라우트 파일 이름 길이를 단순화시킬 수 있다.
Mixed Flat and Directory Routes- 중첩된 라우트를 표현하면서 단일 배열의 단순성을 유지할 수 있다.
Code-Based Routes- 코드 내에서 동적으로 라우트를 정의하는 방식이다.
Case-Sensitivity - 경로의 대소문자 구분을 설정할 수 있는 기능이다.

Root Route (루트 라우트)

가장 최상위 라우트로, 다른 모든 라우트의 기준이 되는 라우트이다.Root Route는 아래와 같은 특징이 존재한다.

  • It has no path (경로가 존재하지 않는다)
  • It is always matched (항상 매치된다)
  • Its component is always rendered (루트 라우트의 컴포넌트는 항상 렌더링 된다)

Root Route는 경로가 없지만 다른 라우트들과 동일한 기능에 접근할 수 있습니다. 예를 들어, 일관된 UI나 상태에 따른 처리 (컴포넌트나 로더, 검색 매개변수의 유효성 검사 등)가 가능합니다.

import { createRootRoute ] from "@tanstack/react-router";

// 가장 최상위 라우트, 전체 라우터 구조 정의 
const rootRoute = createRootRoute(); // 루트 라우트 생성

// context 주입 라우트, 전체 라우터에 공통된 상태나 데이터를 전달 
const contextRoute = createRootRouteWithContext<MyContext>(); // 의존성 주입

Anatoby of a Route(라우트 구조)

Root Route를 제외한 모든 라우트는 FileRoute클래스를 기반으로 구성된다. FileRoute는 파일 기반 라우팅을 사용할 때, 타입 안전성을 제공하는 Route클래스의 래퍼 클래스이다. createFileRoute(path :string)메서드를 사용하여 라우트를 생성한다.

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

// 파일 기반 라우트 생성
export const Route = createFileRoute('/profile')({
  component: ProfileComponent,
})

Static Routes(정적 라우트)

정적 라우트는 특정 경로와 완전히 일치하는 경우에만 매칭이 되는 라우트이다. 간단하고 직관적이다. 

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

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

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

Index Routes(인덱스 라우트)

인덱스 라우트는 부모 라우트가 정확히 매칭되고 자식 라우트가 매칭되지 않았을 때 동작하는 라우트이다. 파일 이름 끝에 index.tsx를 붙여 사용한다. (ex. filename.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

$lable과 같은 형태로 동작하며, params객체에 담아 애플리케이션에서 사용한다.

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>
}

Splat / Catch-all Route

$를 splat이라고 부른다. URL 경로에서 $부터 끝의 문자열까지 params\_splat으로 접근하여 사용할 수 있다.  (Why use $? 파일 이름이나 CLI 도구와의 호환성 문제로 인해 $를 사용하여 처리한다.)


:D Pathless / Layout Routes

_언더스코어로 시작하는 경우, 이를 Pathless / Layout Routes라고 한다. 경로에 직접 매칭되지 않고 다른 컴포넌트를 감싸는 용도로 사용된다. 전체 레이아웃을 정의하거나 공통된 UI 컴포넌트를 제공하는 데 사용된다. (로더나 에러 핸들링 등 서비스 내 공통으로 처리되어야 하는 부분) 파일 이름의 끝에 _layout.tsx를 붙여 표현한다.

레이아웃을 일관되게 유지하고, 자식 페이지에 공통된 설정이나 스타일을 적용하는 데 유용하다.

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

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

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

Non-Nested Routes(비중첩 라우트) #비중첩 라우트 공식문서

특정 부모 라우트와 별도로, 동일한 경로 패턴을 갖지만 독립적으로 작동하는 라우트를 만들 때 사용한다. 일반적으로 라우트는 부모와 자식 관계를 가지지만, 비중첩 라우트는 부모 경로에서 "break out"하여 완전히 다른 컴포넌트 트리를 렌더링 할 수 있다. 부모 파일 이름 뒤에 \_언더 스코어를 붙여 표현한다.

// `posts_.$postId.edit.tsx`
export const EditRoute = createFileRoute('/posts/$postId/edit')({
  component: EditPost,
});

function EditPost() {
  const { postId } = Route.useParams();
  return <div>편집 중인 게시물 ID: {postId}</div>;
}

// `posts.$postId.tsx`
export const PostRoute = createFileRoute('/posts/$postId')({
  component: PostDetail,
});

function PostDetail() {
  const { postId } = Route.useParams();
  return <div>게시물 ID: {postId}</div>;
}

404 / Not Found Routes

요청한 URL이 어떤 라우트와도 일치하지 않는 경우를 표현한다. NotFoundRoute는 라우트 트리에 포함되면 라우트가 제대로 동작하지 않기 때문에 포함시키지 않도록 한다. 또한, pathid를 가지지 않고 경로 파라미터를 파싱하거나 검증할 수 없다는 특징이 있다. 라우트 유효성이 어긋나거나 잘못된 경로를 요청했을 때 발생한다.

참고. https://tanstack.com/router/latest

profile
개발 기록💻

0개의 댓글