Skip to content

Tanstack Router에 대하여...

dannysir edited this page Nov 22, 2024 · 1 revision

TanStack Router React Docs

[번역] TanStack Router를 소개합니다

사용법

전체적인 tanstack-router 사용법은 아래 레포지토리의 코드를 이용해 설명하겠습니다.

GitHub - arackaf/tanstack-router-routing-demo

mian.tsx 파일

아래 코드를 보면 우선 tanstack-router를 사용하기 위해 main 파일에서 선언하는 것을 알 수 있다.

해당 main 함수를 보면 우선 routeTree 라는 녀석이 보이는데 해당 파일은 실행할 때 자동으로 업데이트 되며, 내부에는 경로에 대한 메타 데이터가 들어간다.

import { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider, createRouter } from "@tanstack/react-router";

// Import the generated route tree
import { routeTree } from "./routeTree.gen";

// Create a new router instance
const router = createRouter({ routeTree });

// Register the router instance for type safety
declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router;
  }
}

// Render the app
const rootElement = document.getElementById("root")!;
if (!rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement);
  root.render(
    <StrictMode>
      <RouterProvider router={router} />
    </StrictMode>
  );
}

routes/__root.tsx 파일

아래와 같이 이제 라우트 디렉토리에 있는 루트 파일을 보면 다음과 같이 되어있다. 여기서 createRootRoute 는 단어 그대로 루트를 만드는 함수이다.

Tanstack-Router 장점 1 : Link의 경로를 보고 유효성을 검사해준다.

여기서 내가 생각하는 tanstack-router의 첫번째 장점이 나온다. Link에 잘못된 경로를 추가하게 되면 이전에 만들었던 트리를 이용해 유효성 검사를 하여 개발자에게 바로 알려준다.

Outlet

이제 그 아래부분의 코드를 보면 Outlet 이라는게 보인다. 해당 요소의 경우 해당 레이아웃에 들어갈 내부 컨텐츠를 그곳에 보여준다는 뜻이다. 그럼 여기서 말하는 내부 컨텐츠는 무엇일까? 그건 그 아래 보이는 index.tsx 파일을 보면 알 수 있다.

index.tsx 파일 내부 코드를 읽어보면 “/” 로 루트의 “Index” 컴포넌트라고 선언하는 부분을 볼 수 있다. 해당 방법으로 그 컴포넌트가 해당 요소의 기본 컨텐츠라는 것을 선언할 수 있고 그럼 여기서 선언한 컨텐츠가 Outlet 으로 선언한 부분에 들어가게 되는 것이다.

import { createRootRoute, Link, Outlet } from "@tanstack/react-router";

export const Route = createRootRoute({
  component: () => {
    return (
      <>
        <div className="p-2 flex gap-2">
          <Link to="/" className="[&.active]:font-bold">
            Home
          </Link>
          <Link to="/tasks" className="[&.active]:font-bold">
            Tasks
          </Link>
          <Link to="/epics" className="[&.active]:font-bold">
            Epics
          </Link>
        </div>
        <hr />
        <div className="p-3">
          <Outlet />
        </div>
      </>
    );
  },
});

//routes/index.tsx 파일
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/")({
  component: Index,
});

function Index() {
  return (
    <div className="p-2">
      <h3>Top level index page</h3>
    </div>
  );
}

결과 화면

스크린샷 2024-11-09 오후 4 30 34

2가지 라우팅 방법

  • 파일명을 이용한 라우팅
  • 디렉토리 기반 라우팅

내가 학습한 내용이 맞다면 크게 이렇게 2가지 방법으로 라우팅을 할 수 있는 것 같다.

우리는 분명 루트에서 크게 epics , tasks 두개의 경로로 지정하겠다고 했다. 이점을 유의해서 아래 디렉토리 구조를 보자.

결론적으로 아래 구조를 보면 epics 는 디렉토리를 기준으로 만들었을 때의 구조이고 tasks 는 파일명을 기준으로 만들었을 때의 구조가 될 것이다.

스크린샷 2024-11-09 오후 4 33 42

그럼 이제 하나씩 살펴보자.

만약 내가 Tasks 버튼을 클릭하면 어디로 가게 될까.

//**routes/__root.tsx 파일**
<>
        <div className="p-2 flex gap-2">
          <Link to="/" className="[&.active]:font-bold">
            Home
          </Link>
          <Link to="/tasks" className="[&.active]:font-bold">
            Tasks
          </Link>
          <Link to="/epics" className="[&.active]:font-bold">
            Epics
          </Link>
        </div>
        <hr />
        <div className="p-3">
          <Outlet />
        </div>
      </>

위의 디렉토리 구조를 봤을 때 존재하는 tasks.route.tsx 파일로 우선 넘어가게된다.

그럼 tasks.route.tsx 파일은 아래와 같은 구조로 되어있고

우리는 이제 Outlet 이 무엇인지 알고 있기 때문에 해당 부분에 어떤 것이 들어갈지 추측할 수 있다.

// **tasks.route.tsx**
import { createFileRoute, Outlet } from "@tanstack/react-router";

export const Route = createFileRoute("/tasks")({
  component: () => (
    <div>
      Tasks layout <Outlet />
    </div>
  ),
});

Outlet 에는 tasks.index.tsx 에서 정의한 컨텐츠들이 들어가게 될 것이다.

// **tasks.index.tsx**
import { createFileRoute, Link } from "@tanstack/react-router";

export const Route = createFileRoute("/tasks/")({
  component: Index,
});

function Index() {
  const tasks = [
    { id: "1", title: "Task 1" },
    { id: "2", title: "Task 2" },
    { id: "3", title: "Task 3" },
  ];

  return (
    <div className="p-2">
      <h3>Tasks page!</h3>
      <div className="flex flex-col gap-2 p-3">
        {tasks.map((t, idx) => (
          <div key={idx} className="flex gap-3">
            <div>{t.title}</div>
            <Link to="/tasks/$taskId" params={{ taskId: t.id }}>
              View
            </Link>
            <Link to="/tasks/$taskId/edit" params={{ taskId: t.id }}>
              Edit
            </Link>
          </div>
        ))}
      </div>
    </div>
  );
}

여기까지 진행했으면 이제 디렉토리 기반으로 되어있는 epics 는 구조만 확인해도 이해가 될 것이다.

앞서 보여주었던 디렉토리 구조를 다시 한번 살펴보자.

스크린샷 2024-11-09 오후 4 33 42

사용자가 url에서 /epics 로 가게 되면 epics 디렉토리에 있는 epics/route.tsx 로 들어가게 될 것이다.

그후 epics/route.tsx 코드에 있는 Outlet 을 통해 컨텐츠를 표시할 위치가 정해져 있을 것이고 내부 컨텐츠의 경우 epics/index.ts 를 통해 알려줄 것이다.

결론.

솔직하게 디렉토리 구조만으로 라우팅이 되는 전체적인 모습을 상상할 수 있다는 장점과 경로 유효성 검사를 해준다는 장점만으로는 아직 React-router에서 굳이 바꿔야할 필요성을 못느끼겠다.

또한 아직 출시한지 오래되지 않았기 때문에 조금 보수적으로 다가갈 필요가 있어보인다.

📜 개발 일지

⚠️ 트러블 슈팅

❗ 규칙

🗒️ 기록

기획
회의록
데일리스크럼
그룹 멘토링
그룹 회고

😲 개별 멘토링

고동우
김진
서산
이시은
박진명
Clone this wiki locally