Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

Next.js 에서 라우팅 사용하기 본문

🎨 프론트엔드/Next.js

Next.js 에서 라우팅 사용하기

Chamming2 2021. 2. 22. 02:37

리액트에서는 react-router-dom 라이브러리를 통해 페이지간 라우팅을 구현할 수 있었습니다.

그러나 넥스트(Next.js) 에서는 pages 폴더 안에 컴포넌트를 생성하면 자동으로 경로가 설정되게 됩니다.

/.next
/pages
  ㄴ-- index.jsx
  ㄴ-- tomato.jsx
/public
/styles

이렇게 pages 폴더 안에 index 와 tomato 라는 컴포넌트가 있으면 별도의 라우팅 없이 /tomato 라는 경로를 사용할 수 있게 됩니다.

(* 경로명은 export되는 컴포넌트 이름이 아닌 파일명을 기준으로 합니다.)

정적 라우팅

정적 라우팅은 사전에 지정된 주소로 이동하는 방법입니다.

react-router-dom 처럼 넥스트에서도 Link 컴포넌트를 사용해 주소를 이동할 수 있습니다.

import Link from "next/Link";

export default function App() {
  return (
    <div>
      <h2>Link to 'tomato' Page</h2>
      <Link href="/tomato">
        <a>move to tomato</a>
      </Link>
    </div>
  );
}

Link 컴포넌트는 next/Link 모듈에서 불러와 사용할 수 있으며 href 속성으로 이동할 경로를 지정합니다.

Link 컴포넌트로 감싼 요소를 클릭하면 지정한 경로로 이동하게 되는데요, 다만 컴포넌트를 감쌀 시에는 라우팅이 이루어지지 않습니다.

// a 태그를 감싸 사용 - OK
<Link href="/tomato">
  <a>move to tomato</a>
</Link>

// p 태그를 감싸 사용 - OK (다만 웹 접근성을 감안하면 좋은 방법이 아님)
<Link href="/tomato">
  <p>move to tomato</p>
</Link>

// 임의의 NewLink 컴포넌트를 감싸 사용 - BAD
<Link href="/tomato">
  <NewLink>move to tomato</NewLink>
</Link>

또 링크 컴포넌트는 브라우저의 History API를 지원하여 뒤로가기를 하더라도 이전에 렌더링한 페이지를 불러옵니다.

따라서 새 페이지를 불러오기 위한 요청을 하지 않아도 되며, 이전 페이지를 다시 컴파일할 필요가 없다는 장점이 있습니다.

동적 라우팅

사전에 지정된 주소로의 정적 라우팅을 알아보았는데요, 동적인 주소로의 라우팅도 가능합니다.

/.next
/pages
  ㄴ-- index.jsx
  ㄴ-- /vegetable
         ㄴ-- [name].jsx
/public
/styles

이렇게 대괄호 [] 로 파일명을 감싸면 해당 페이지는 동적으로 경로가 지정되는 페이지가 됩니다.

이제 동적 페이지가 존재하는 경로에 임의의 주소를 대입하면 대입한 주소를 쿼리명으로 갖는 페이지로 이동할 수 있습니다.

import Link from "next/Link";

export default function App() {
  return (
    <div>
      <h2>Link to 'potato' Page</h2>
      <Link href="/vegetable/potato">
        <a>move to /vegetable/potato</a>
      </Link>
    </div>
  );
}

(* Next.js 9.5.3 이전 버전에서는 Link 컴포넌트의 속성을 다음과 같이 작성합니다.)

<Link href="/vegetable/[name]" as="/vegetable/potato">

그리고 당연하지만, 한 동적 경로에는 한 개의 동적 페이지만이 존재할 수 있습니다.

/.next
/pages
  ㄴ-- index.jsx
  ㄴ-- /vegetable
         ㄴ-- [name].jsx
         ㄴ-- [item].jsx -> Error!
/public
/styles

라우터 객체 

이번에는 경로 정보를 담고 있는 라우터 객체를 한번 살펴보도록 하겠습니다.

라우터 객체는 next/router 모듈에서 useRouter 훅을 불러와 사용할 수 있습니다.

 

방금 생성한 [name].jsx 파일을 다음과 같이 작성하고 라우터 객체의 형태를 살펴봅시다.

import React from "react";
import Link from "next/link";
import { useRouter } from "next/router";

const name = () => {
  const router = useRouter();
  console.log(router); // 라우터 객체를 출력합니다.
  
  return (
    <div>
      <h2>Hello!</h2>
      <Link href="/">Move to main</Link>
    </div>
  );
};

export default name;

[name].jsx 페이지를 만들어 동적 라우팅을 소개할 때 vegetable/potato 라는 주소로 경로를 지정했었는데요, 동적으로 지정한 potato 라는 값이 쿼리에 들어가있는 모습을 확인할 수 있습니다. 

 

만약 [item].jsx 페이지를 만들고 newItem 이라는 동적 경로를 사용하면 {item: "newItem"} 이라는 쿼리를 확인할 수 있습니다.

라우터 객체로 라우팅 수행하기

지금까지는 Link 컴포넌트를 활용해 라우팅을 진행했지만, 가끔은 함수나 로직 내에서 라우팅을 수행해야 할 때가 있습니다.

import { useRouter } from "next/router";

export default function App() {
  const router = useRouter();
  return (
    <div>
      <h2>Link to 'tomato' Page</h2>
      <button onClick={() => router.push("/tomato")}>토마토로 가기</button>
    </div>
  );
}

이벤트 핸들러를 통해 라우팅을 수행하는 위의 예시처럼 함수 내에서 라우팅을 수행하기 위해서는 라우터 객체를 활용할 수 있습니다.

주로 사용되는 함수는 back / push / replace 로 각 함수의 설명은 다음과 같습니다.

 

- router.back() : 직전 페이지로 돌아갑니다.

- router.push("url") : 지정한 경로로 이동하며 히스토리 스택에 URL를 추가합니다.

- router.replace("url") : 지정한 경로로 이동하나 히스토리 스택에 URL를 추가하지 않습니다.

 

그러나 SEO에 영향을 미치는 크롤러는 router.push() 가 다른 페이지로 이동하는 링크라고 인식하지 않습니다.

따라서 이벤트 핸들러 등에 필요한 경우가 아니라면 Link 컴포넌트를 활용해 시멘틱한 구조를 유지하는 것을 권장합니다.

(* 참고 링크 - stackoverflow.com/questions/65086108/next-js-link-vs-router-push-vs-a-tag)

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆