๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿ“บ Front End/- React, Next.js

[Next js] Next์˜ Dynamic Routing๊ณผ Link ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ์•„์ฃผ ๊ฐ„๋‹จํ•œ ๊ฒŒ์‹œํŒ ๋งŒ๋“ค๊ธฐ.

by Wonit 2020. 12. 29.

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” Next JS ์˜ Dynamic Routing ์„ ์ด์šฉํ•ด์„œ ๊ฒŒ์‹œํŒ์„ ๋งŒ๋“ค์–ด ๋ณผ ๊ฒƒ์ด๋‹ค.

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ด๋ก ์ ์ธ ์ด์•ผ๊ธฐ ๋ณด๋‹ค ์ข€ ๋” ์‹ค์šฉ์ ์ธ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

 

๋งŒ์•ฝ ๋‹ค์ด๋‚˜๋ฏน ๋ผ์šฐํŒ…์— ๋Œ€ํ•ด์„œ ์•Œ์ง€ ๋ชปํ•˜๊ฑฐ๋‚˜ ํ•œ๊ธ€๋กœ ์ •๋ฆฌ๋œ ๊ธ€์„ ๋ณด๊ณ ์‹ถ๋‹ค๋ฉด ์ด๊ณณ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ Link ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด์„œ๋Š” ์ด๊ณณ์— ์ •๋ฆฌ๋ฅผ ํ•ด๋†จ์œผ๋‹ˆ ํ•œ ๋ฒˆ ๊ฐ€๋ณ๊ฒŒ ์ฝ๊ณ  ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.


์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” Dynamic Routing๊ณผ Link๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ„๋‹จํ•œ ๊ฒŒ์‹œํŒ์„ ๋งŒ๋“ค์–ด๋ณผ ๊ฒƒ์ด๋‹ค.

 

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ชฉ์ ์€ ๋ฐ”๋กœ Dynamic Routing๊ณผ Link ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์˜นํ•˜๋Š” ๊ฒƒ ์ด๋‹ค.

 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธ์ด๋‚˜ Express, Node, DB์™€ ๊ฐ™์ด ๊ณ ๊ธ‰ ๊ธฐ์ˆ  ๊ทธ๋ฆฌ๊ณ  ์‰ฌ์šด ๋””์ž์ธ์  ์š”์†Œ๋„ ํ•˜๋‚˜๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ผ์šฐํŒ…์„ ์ค‘์ ์ ์œผ๋กœ ํ™•์ธํ•  ๊ฒƒ์ด๋‹ค.

Directory ๊ตฌ์กฐ

๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋Š” ๋ผ์šฐํŒ…์„ ํ•  pages ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— post/[id] ๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์— comment ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€์‹œํ‚ฌ ๊ฒƒ์ด๋‹ค.

 

  • pages : ๋ผ์šฐํŒ…์„ ํ•  ํŒŒ์ผ์„ ๋ชจ์•„๋†“๋Š” ๋””๋ ‰ํ† ๋ฆฌ
  • components : Navigation bar ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  <Header> ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ–๋Š” ๋””๋ ‰ํ† ๋ฆฌ

File ๊ตฌ์กฐ

  • pages/index.jsx => localhost:3000/ ๊ณผ ๋งคํ•‘๋  jsx ํŒŒ์ผ
  • pages/about.jsx => localhost:3000/about ๊ณผ ๋งคํ•‘๋  jsx ํŒŒ์ผ
  • pages/post/[id]/index.jsx => localhost:3000/post ์™€ ๋งคํ•‘๋  jsx ํŒŒ์ผ
  • pages/post/[id]/[comment].jsx => localhost:3000/post/1/first-comment ๊ณผ ๋งคํ•‘๋  jsx ํŒŒ์ผ

components/Header.jsx

import React from "react";
import Link from "next/link";
const Header = () => {
  return (
    <header>
      <ul>
        <li>
          <Link href="/">
            <a>home</a>
          </Link>
        </li>
      </ul>
      <ul>
        <li>
          <Link href="/about">
            <a>About</a>
          </Link>
        </li>
      </ul>
      <ul>
        <li>
          <Link href="/post/[id]" as="/post/first">
            <a>First Post</a>
          </Link>
        </li>
      </ul>
      <ul>
        <li>
          <Link href="/post/[id]" as="/post/second">
            <a>Second Post</a>
          </Link>
        </li>
      </ul>
    </header>
  );
};

export default Header;

Components ์—์„œ ๋ชจ๋“  ํŽ˜์ด์ง€๊ฐ€ ๊ฐ–๊ฒŒ๋  Header ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค.

Header ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒ๋‹จ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ”์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•  ๊ฒƒ์ธ๋ฐ, ์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ๊ฒƒ์€ ๋ฐ”๋กœ
<Link href="/post/[id]" as=""> ์—์„œ as์˜ ์—ญํ• ์ด๋‹ค.

  • as Props๋Š” ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์— ๋”ฐ๋ฅด๋ฉด ๋ธŒ๋ผ์šฐ์ € URL ํ‘œ์‹œ์ค„์— ํ‘œ์‹œ๋  ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ์„ ํƒ์  decorator. ์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ as ํ”„๋กญ์Šค๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด๋‹น Link ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์–ด๋–ค url๋กœ ์ด๋™์‹œํ‚ฌ์ง€ ๋ช…์‹œํ•ด์ค„ ๊ฒƒ์ด๋‹ค.

pages/index.jsx

import Link from "next/link";
import Header from "../components/Header";

function Home() {
  return (
    <>
      <Header />
      <h1>About page</h1>
    </>
  );
}

export default Home;

์ด์ œ ์‹ค์งˆ์ ์œผ๋กœ localhost:3000/์œผ๋กœ ๋“ค์–ด๊ฐ”์„ ๋•Œ ๋ผ์šฐํŒ…์„ ํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.
pages ์•ˆ์— index.js๋Š” default ๊ฒฝ๋กœ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

pages/about.jsx

import React from "react";

const about = () => {
  return <div>this is about</div>;
};

export default about;

about.jsx๋Š” ๋™์  ๋ผ์šฐํŒ…๊ณผ ๋ณ„๊ฐœ๋กœ ์ผ๋ฐ˜์ ์ธ ๋ผ์šฐํŒ…์„ ์œ„ํ•ด ์ถ”๊ฐ€ํ•˜์˜€๋‹ค.

pages/post/[id]/index.jsx

import { useRouter } from "next/router";
import Link from "next/link";
import Header from "../../../components/header";

const Post = () => {
  const router = useRouter();
  const { id } = router.query;

  return (
    <>
      <Header />
      <h1>Post: {id}</h1>
      <ul>
        <li>
          <Link href="/post/[id]/[comment]" as={`/post/${id}/first-comment`}>
            <a>First comment</a>
          </Link>
        </li>
        <li>
          <Link href="/post/[id]/[comment]" as={`/post/${id}/second-comment`}>
            <a>Second comment</a>
          </Link>
        </li>
      </ul>
    </>
  );
};

export default Post;

์•„๊นŒ ๋ดค๋“ฏ์ด components/Header.jsx์—์„œ as ํ”„๋กญ์Šค๋กœ ์–ด๋–ค ๊ณณ์œผ๋กœ ๊ฐˆ์ง€ ์ง€์ •ํ•ด ์ค€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค„ ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.
์—ฌ๊ธฐ์„œ๋„ ๋Œ“๊ธ€๋“ค์„ asํ”„๋กญ์Šค๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ๋ณด์ž.

pages/post/[id]/[comment]/.jsx

import { useRouter } from "next/router";
import Header from "../../../components/header";
const Comment = () => {
  const router = useRouter();
  const { id, comment } = router.query;

  return (
    <>
      <h1>Post: {id}</h1>
      <h1>Comment: {comment}</h1>
    </>
  );
};

export default Comment;

์œ„์™€ ๊ฐ™์€ ๊ณผ์ •์˜ ์—ฐ์†์ด๋‹ค.


์˜ค๋Š˜์€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง€๋ฅผ ๋งํฌํ•˜๋ฉฐ ๋™์ ์œผ๋กœ ๋ผ์šฐํŒ…์„ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋‹ค.

๋Œ“๊ธ€