유용한 유형: TypeScript로 경로 트리 구축

안녕!

이전 기사에서 경로의 매개변수 유형을 추출하는 방법을 썼습니다. 아직 못 보셨다면 보세요. 이제 프로젝트에서 경로 정의를 만드는 방법을 설명하겠습니다.

우선, 다음에 사용될 몇 가지 용어를 정의해 봅시다. react-router-dom@6nested routes을 사용할 수 있으므로 다음과 같이 정의할 수 있습니다.

<Route path="/">
  <Route path="card" element={...}>
    <Route path=":cardId" element={...}>
      {...}
    </Route>
  </Route>
</Route>


위의 코드에서 / , card:cardId 는 일부 경로의 파괴된 세그먼트입니다. 합류하면 /card/:cardId 가 됩니다. 따라서 이러한 세그먼트 중 하나를 apath라고 하고 일부 루트에서 지정된 각 경로로 결합된 세그먼트를 afullPath라고 합니다.

어떤 경우에는 path를 사용하고 다른 경우에는 fullPath를 사용해야 합니다. 그리고 제 생각에는 모든 단일 경로 정의에 대한 모든 데이터는 한 곳에 저장되어야 합니다. 또한 이 정의에는 경로에 대한 다른 정보(예: 페이지 제목, 기본 쿼리 매개변수, 일부 플래그 등)가 있을 수 있습니다. 그리고 원인은 위의 코드 때문에 경로 정의를 트리로 정의하고 싶습니다.

간단히 내 이상적인 경로 정의:
  • 트리
  • 로 만들 수 있습니다.
  • 은 필요한 모든 데이터를 각 노드
  • 에 저장합니다.
  • 강력한 유형을 자동으로 유추합니다(네, 필요합니다)
  • 은 애플리케이션 전체에서 공유되는 한 번 선언된 구조입니다
  • .

    먼저 강력한 형식의 트리를 만드는 방법을 살펴보겠습니다. 이를 위해 an intersection of object typesgenerics을 사용할 수 있습니다. 정의하자a type

    type SomeData<Other> = {
      path: string;
    } & Other;
    


    따라서 SomeDatapath 속성과 Other의 다른 속성을 정의합니다.

    const q1: SomeData<{}> = {path: ""}
    let q2: SomeData<{a: number}> = {path: "", a: 10}
    let q3: SomeData<{nested: SomeData<{}>}> = {
      path: "",
      nested: {path: ""}
    }
    


    이 솔루션은 라우팅 정의의 트리형 유형을 정의할 수 있지만 수동으로 유형을 작성해야 합니다. 따라서 정의 개체를 생성하고 해당 유형을 자동으로 유추하는 선언some function을 할 수 있습니다.

    type RouteDefinition<Nested> = {
      path: string;
    } & Nested;
    
    function route<Nested>(
      path: string,
      nested: Nested
    ): RouteDefinition<Nested> {
      return {
        path,
        ...nested,
      }
    }
    


    이 경우 함수route를 사용하여 하나의 라우팅 정의 노드를 생성한 다음 중첩 정의에 함수를 재사용할 수 있습니다.

    const q1 = route("card", {}); // {path: "card"}
    const q2 = route("card", {
      a: route("a", {})
    }); // {path: "card", a: {path: "a"}}
    


    지금은 그다지 편리하지 않은 것처럼 보일 수 있지만 나중에 이에 대해 다시 설명하겠습니다.

    전체 경로 속성은 어떻습니까? 정의 노드 내에서 전체 경로의 한 부분을 정의하고 모든 중첩된 정의는 전체 경로에 이 접두사를 포함해야 합니다. 나는 to change nested 개체를 첫 번째 매개 변수로 모든 중첩된 경로의 전체 경로를 취하고 중첩된 경로 정의를 반환하는 함수에 제안합니다.

    먼저 fullPath 속성을 RouteDefinition 유형에 추가합니다.

    type RouteDefinition<Nested> = {
      path: string;
      fullPath: string;
    } & Nested;
    


    그런 다음 prefix 매개변수를 route 함수에 추가해야 중첩된 전체 경로로 노드를 정의할 수 있습니다. 또한 nested 개체를 위에서 설명한 createNested 함수로 변경합니다. 보다 편리한 사용을 위해 선택 사항으로 만들자.

    function route<Nested>(
      path: string,
      prefix: string,
      createNested?: (fullPath: string) => Nested,
    ): RouteDefinition<Nested> {
      const fullPath = `${prefix}/${path}`
      const nested = createNested 
        ? createNested(fullPath) 
        : ({} as Nested);
    
      return {
        path,
        fullPath,
        ...nested,
      }
    }
    


    이제 이 함수를 사용하여 다음과 같은 중첩된 경로를 정의할 수 있습니다.

    const q1 = route("card", ""); // {path: "card", fullPath: "/card"}
    
    const q2 = route("card", "", prefix => ({
      a: route("a", prefix),
      b: route("b", prefix, prefix => ({
        c: route("c", prefix)
      }))
    })); 
    /**
      {
        path: "card",
        fullPath: "/card",
        a: {
          path: "a",
          fullPath: "/card/a"
        },
        b: {
          path: "b",
          fullPath: "/card/b",
          c: {
            path: "c",
            fullPath: "/card/b/c"
          }
        }
      }
     */
    


    모든 경로 정의를 객체로 생성하고 애플리케이션 전체에서 공유할 수 있습니다. title , isModal 등과 같은 다른 속성을 노드 정의에 추가할 수도 있습니다. 또한 이러한 접근 방식은 경로 트리를 생성하는 것뿐만 아니라 트리와 같은 구조를 생성하는 데에도 사용할 수 있습니다.

    다음 기사에서는 url의 매개변수로 작업하는 방법과 url 매개변수에 의존하는 경로 정의의 속성을 빌드하는 방법을 설명하고 싶습니다. 팔로우 하시고 다음 글에서 뵙겠습니다.

    좋은 웹페이지 즐겨찾기