코딩/React

Remix 프레임워크 Nested Routing 파헤치기

드리프트 2022. 3. 17. 17:27
728x170
Remix Framework File-base Routing and Nested Routing ( 리믹스 프레임워크 파일 베이스 라우팅, 네스티드 중첩 라우팅)

 

 

안녕하세요?

 

오늘은 지난번에 간단하게 알아봤던 Remix 프레임워크에 대해 좀 더 심도 있게 들어가 보도록 하겠습니다.

 

NextJS가 처음 나왔을 때 리액트쪽에서는 굉장한 반향이 일어났었는데요.

 

바로 NextJS의 파일 베이스 라우팅이 그 주인공이었습니다.

 

물론 Static Site Generating과 Server Side Rendering도 중요한 기능이었지만요.

 

일반적으로 리액트 라우터를 쓰는 SPA 수준의 리액트에서는 라우팅 하는데 꾀나 고달팠는데요.

 

NextJS의 파일 베이스 라우팅의 소개로 그 수고스러움이 싹 사라졌다고 생각합니다.

 

리믹스에서도 파일베이스 라우팅이 쓰이고 있고 더 나아가 Nested Routing 중첩 라우팅도 지원하는 게 그 기능이 아주 막강합니다.

 

오늘은 리믹스의 라우팅에 대해 알아보겠습니다.

 

참고로 리믹스의 라우팅은 리액트 라우터 버전 6을 이용해서 파일 베이스 라우팅으로 구현한 겁니다.

 

 

File Base Routing

 

일단 지난 시간에는 리믹스 프레임워크의 설치 및 TailwindCSS 적용에 대해 알아보았는데요.

 

리믹스 설치 쪽에서 라우팅의 가장 기본이 되는 폴더가 바로 app 폴더 밑의 routes 폴더였습니다.

 

NextJS에서는 pages 폴더 밑에 있는 파일이나 디렉터리가 라우팅의 재료로 쓰이지만 리믹스에서는 app 폴더 밑에 routes 폴더를 따로 두었습니다.

 

그리고 routes 폴더 밑에는 index.tsx 파일이 있는데요.

 

우리가 만들려고 하는 홈페이지의 첫 스타팅 포인트가 바로 이 index.tsx파일입니다.

 

크롬 브라우저로 보시면 위 그림처럼 포트 3000 밑에 아무것도 없죠.

 

웹의 초창기부터 서버의 운영방식은 index.html 파일이 모든 페이지의 시초였습니다.

 

그래서 보통 index로 시작하는 파일을 그 시초로 인식하게 됩니다.

 

위의 주소창은 사실 http://localhost:3000/라고 루트(root) 폴더인 "/"만 있는 경우인데요.

 

이럴 경우 리믹스 프레임워크나 넥스트 JS나 모두 index.tsx(jsx) 파일을 불러오게 됩니다.

 

자, app 폴더 밑의 routes 폴더 밑에 index.tsx가 시초라고 했으니까 다른 페이지를 하나 만들어 볼까요?

 

http://localhost:3000/test라는 경로로 만들려면 어떻게 해야 할까요?

 

그냥 routes 폴더 밑이 test.tsx(jsx) 파일을 만들면 됩니다.

 

VS Code에서 test.tsx 파일을 만들었습니다.

 

이제 브라우저에서 test 경로로 이동해 볼까요?

 

서버 에러가 떴습니다. 왜 그런 걸까요?

 

바로 리믹스가 test.tsx 파일의 존재를 보고 test라는 라우팅을 만들었는데, 실제 test.tsx 파일 안에는 브라우저에 보여줄 수 있는 DOM이 아무것도 없어서 그런 겁니다.

 

이제 실제 파일에 빈 리액트 컴포넌트를 작성해 보겠습니다.

 

export default function Test() {
  return <div>This is Test</div>;
}

 

이제 브라우저를 볼까요?

 

브라우저에서 test 페이지를 제대로 로딩하고 있습니다.

 

이렇듯 routes 폴더 밑에 어떤 파일 이름이든 그 이름으로 라우팅 주소가 생성되는 걸 알 수 있습니다.

 

그러면 routes 폴더 밑에 또 폴더가 있으면 어떻게 될까요?

 

테스트를 위해 routes 폴더 밑에 child 란 폴더만 만들어 봅시다.

 

이제 브라우저에서 child 경로로 이동해 볼까요?

 

http://localhost:3000/child

 

위 그림처럼 404 에러가 나타났습니다.

 

자료가 없다는 뜻이죠.

 

왜냐하면 child는 폴더이니까 그 폴더 밑에 가장 기본이 되는 index.tsx(jsx) 파일이 없어서 그런 겁니다.

 

export default function Child() {
  return <div className="text-red-500">This is Child</div>;
}

이제 위와 같은 코드를 /app/routes/child/index.tsx 파일로 저장하겠습니다.

 

app 폴더 밑에 routes 폴더가 있고 그 밑에 child 폴더가 있으니까 브라우저 주소창으로는 http://localhost:3000/child가 됩니다.

 

이제 좀 더 깊은 테스트를 위해 child 폴더 밑에 child-test.tsx라는 파일을 만들어 보겠습니다.

export default function ChildTest() {
    return(
        <div className="text-blue-500">This is Test of Child</div>
    )
}

 

그러면 브라우저 경로는 어떻게 될까요?

 

바로 http://localhost:3000/child/child-test 가 됩니다.

 

여기까지 따라오셨다면 바로 리믹스나 넥스트 JS의 파일 베이스 라우팅에 대해 이해하셨다고 봐도 무방합니다.

 

 

레이아웃 라우트(Layout Routes)

 

레이아웃 라우트의 예를 들기 위해 child 폴더 밑에 있는 child-test.tsx 파일과 더불어 child-test2.tsx 파일을 또 만들어 봅시다.

 

export default function ChildTest2() {
    return(
        <div className="text-cyan-500">This is Test2 of Child</div>
    )
}

 

그럼 child 폴더의 폴더 구조를 볼까요?

 

 

child 폴더 밑에는 child 폴더의 기본 라우팅인 index.tsx가 있고 child-test.tsx 파일과 child-test2.tsx 파일이 있습니다.

 

즉, child 폴더 밑에는 총 3개의 파일이 있다는 뜻인데요.

 

만약에 예를 들어 child 폴더 밑에 있는 3개의 파일의 스타일을 일괄적으로 적용시킬 layout 컴포넌트가 필요하더면 어떻게 해야 할까요?

 

NextJS나 리액트에서는 Layout 컴포넌트를 만들고 Layout 컴포넌트를 _app.tsx 파일에 넣고 그 밑에 children prop을 넣어서 해결했는데요.

 

리믹스에서는 다른 방식으로 합니다.

 

child 폴더의 레이아웃을 지정하려면 바로 child 폴더와 같은 이름의 child.tsx 파일을 child 폴더 위에 즉, child 폴더와 같은 위치에 작성하시면 됩니다.

 

우리의 예제에서는 routes 폴더 밑에 child 폴더가 있는 경우니까 바로 routes 폴더 밑에 child.tsx 파일을 만드는 경우입니다.

 

즉, 파일 베이스 라우팅으로 볼 때 http://localhost:3000/child라고 했을 때 리믹스는 child.tsx 파일도 있고 child 폴더도 있고 2중의 선택을 해야 하는데요.

 

이때 레이아웃 라우팅이 일어나게 됩니다.

 

한번 해볼까요?

 

export default function Child() {
  return <div className="p-10">This is Layout Route of Child</div>;
}

 

결과는 child 폴더 밑의 index.tsx 파일이 로드된 게 아니라 routes 폴더 밑의 child.tsx 파일이 로드되었습니다.

 

즉, 우선순위가 레이아웃 라우트가 더 우선이라는 얘기죠.

 

그러면 child 폴더 밑의 child-test 경로로 이동해 볼까요?

 

이상하게 아까라 똑같습니다.

 

왜 그런 걸까요?

 

바로 리액트의 children 프랍을 전달 안 했기 때문인데요.

 

리믹스에서는 서브 폴더의 컴포넌트를 대신하는 컴포넌트가 바로 Outlet 컴포넌트입니다.

 

이제 routes 폴더에 있는 child.tsx 폴더를 아래와 같이 바꾸어 봅시다.

 

import { Outlet } from "remix";

export default function Child() {
  return (
    <>
      <div className="p-10">This is Layout Route of Child</div>
      <div className="p-10">
        <Outlet />
      </div>
    </>
  );
}

<Outlet /> 컴포넌트는 당연히 remix에서 import 해야 합니다.

 

이제 다시 child-test 주소로 가볼까요?

 

레이아웃 라우팅의 문구도 나오고 그 밑에 child-test.tsx 파일의 문구도 나오는데 child-test.tsx파일의 문구는 p-10이라는 즉, 패딩 10 이라는 스타일도 적용되었습니다.

 

왜냐하면 child.tsx 파일에서 <Outlet />을 감싸는 div에 p-10을 줬기 때문입니다.

 

일종의 레이아웃 스타일링을 준 건데요.

 

 

child-test2 로도 가보겠습니다.

 

 

child-test2 폴더도 아주 잘 됩니다.

 

그럼 그냥 child 경로로 가볼까요?

 

 

보시면 Layout Route과 함께 child 폴더 밑의 index.tsx 파일이 함께 로드되었습니다.

 

만약 child 폴더 밑의 index.tsx 파일을 지우면 어떻게 될까요?

 

당연히 아래와 같이 레이아웃 라우팅만 보이게 되죠.

 

이제, 레이아웃 라우팅에 대해 조금은 알 거 같은데요.

 

만약 child 폴더 밑에 다른 레이아웃을 적용하고 싶다는 할 때는 어떻게 할까요?

 

이럴 때 하는 방법은 파일 이름을 점 단위로 만들면 됩니다.

 

아래 트리구조처럼 child.other.tsx 파일을 child.tsx 파일과 같은 위치에 만들면 됩니다.

 

export default function Child() {
  return <div className="text-red-500">This is Child</div>;
}

 

 

만약에 child.other.tsx 파일이 child 폴더 안에 있다면 이 파일도 똑같은 레이아웃 라우팅의 영향을 받게 됩니다.

 

그래서 경로를 더 깊게 내려가려면 단순히 점을 많이 찍어주면 됩니다.

 

child.other.another.tsx 파일 이름처럼 하면 됩니다.

 

 

 

 

 

어떤가요? 리믹스 프레임워크의 파일 베이스 라우팅과 레이아웃 라우팅의 강력한 기능을 보셨죠?

 

이 원리를 잘 이용하신다면 NextJS에 버금가는 훌륭한 홈페이지를 만들 수 있을 겁니다.

그리드형