Next.js (Dynamic route, useRouter, ์„œ๋ฒ„ ๊ธฐ๋Šฅ)

I'm ยท2023๋…„ 6์›” 14์ผ
0

Next.js

๋ชฉ๋ก ๋ณด๊ธฐ
4/4

๐Ÿซ  Dynamic route

  • ํด๋” ํ•˜๋‚˜๋กœ ์ˆ˜๋งŽ์€ URL์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

dynamic route ๋งŒ๋“œ๋Š” ๋ฒ•

  • ํด๋”์ด๋ฆ„์„ [ํด๋”์ด๋ฆ„] ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๋ฉด '์ด ๋ถ€๋ถ„์— ์•„๋ฌด๊ฑฐ๋‚˜ ์ž…๋ ฅํ–ˆ์„ ๋•Œ' ๋ผ๋Š” ๋œป์ด ๋ฉ๋‹ˆ๋‹ค.

MongoDB์—์„œ ๊ฒŒ์‹œ๋ฌผ ํ•˜๋‚˜๋งŒ ์ฐพ์•„์„œ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด?

  const result = await db
    .collection("post")
    .findOne({ _id: new ObjectId("64880201097b4e89b21843f3") });
  • findOne()์•ˆ์— object ์ž๋ฃŒ๋ฅผ ๋„ฃ์œผ๋ฉด ๊ทธ ๋‚ด์šฉ์ด ํฌํ•จ๋œ document ํ•˜๋‚˜๋ฅผ ๊ฐ€์ ธ๋‹ค์ค๋‹ˆ๋‹ค.

  • ObjectID import ํ•ด์™€์•ผํ•ฉ๋‹ˆ๋‹ค.

์œ ์ €๊ฐ€ URL์— ์ž…๋ ฅํ•œ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๋Š” ๋ฒ•

  • page.js ์ปดํฌ๋„ŒํŠธ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์•„๋ฌด๊ฑฐ๋‚˜ ๋“ฑ๋กํ•ด๋‘๋ฉด [ํด๋”์ด๋ฆ„] ์ž๋ฆฌ์— ์œ ์ €๊ฐ€ ์ž…๋ ฅํ•œ ๋‚ด์šฉ์„ props ๋ณ€์ˆ˜์— ์ž๋™์œผ๋กœ ๋‹ด์•„์ค๋‹ˆ๋‹ค.

console.log(props) ํ•˜๋ฉด

{ params: { id: '1' }, searchParams: {} } ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

๐Ÿซ  useRouter

  • client component ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅ
"use client";

import { useRouter } from "next/navigation";

export default function DetailLink() {
  const router = useRouter();
  return (
    <button
      onClick={() => {
        router.push("/");
      }}
    >
      ๋ฒ„ํŠผ
    </button>
  );
}
  • push : ํŽ˜์ด์ง€ ์ด๋™
  • back : ๋’ค๋กœ๊ฐ€๊ธฐ
  • forward : ์•ž์œผ๋กœ๊ฐ€๊ธฐ
  • refresh : ๋ฐ”๋€๋‚ด์šฉ๋งŒ ์ƒˆ๋กœ๊ณ ์นจ(soft refresh)
  • prefetch : ํŽ˜์ด์ง€ ๋ฏธ๋ฆฌ๋กœ๋“œ (url์˜ ๋‚ด์šฉ์„ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•ด์ค๋‹ˆ๋‹ค.)

Link ํƒœ๊ทธ์—๋„ prefetch ๊ธฐ๋Šฅ ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
prefetch ๊ธฐ๋Šฅ ๋„๊ณ  ์‹ถ์œผ๋ฉด prefetch ์†์„ฑ์„ false๋กœ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<Link prefetch={false} href={`/detail/${data._id}`}>
  • usePathname() : ํ˜„์žฌ URL ์ถœ๋ ฅ
  • useSearchParams() : Search parameter(query string) ์ถœ๋ ฅ
  • useParams() : dynamic route์— ์ž…๋ ฅํ•œ ๋‚ด์šฉ

๐Ÿซ  Next.js์—์„œ ์„œ๋ฒ„๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

ex) /pages/api/test.js

  • pages ํด๋” ์•ˆ์— ๋งŒ๋“  ํŒŒ์ผ๊ณผ ํด๋”๋Š” ์ž๋™์œผ๋กœ ์„œ๋ฒ„๊ธฐ๋Šฅ์˜ URL์ด ๋ฉ๋‹ˆ๋‹ค. (/api/test)
  • ์œ ์ €๊ฐ€ /api/test ๋ผ๋Š” URL๋กœ GET/POST/PUT/DELETE ์š”์ฒญํ•˜๋ฉด test.js ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
import { connectDB } from "@/util/database";

export default async function handler(req, res) {
  const db = (await connectDB).db("forum");
  const result = await db.collection("post").find().toArray();
  if (req.method === "GET") {
    return res.status(200).json(result);
  }
}

์„œ๋ฒ„๋กœ POST method ์š”์ฒญํ•˜๋ ค๋ฉด

      <form action="/api/post/new" method="POST">
        <input name="title" placeholder="๊ธ€์ œ๋ชฉ" />
        <input name="content" placeholder="๊ธ€๋‚ด์šฉ" />
        <button>๋ฒ„ํŠผ</button>
      </form>
  • action์—๋Š” URL ๊ธฐ์ž…, method๋Š” GET, POST ์ค‘์— ํ•˜๋‚˜ ๊ธฐ์ž…

  • ๊ทธ URL๊ณผ method๋กœ ๋งŒ๋“ค์–ด๋†“์€ ์„œ๋ฒ„๊ธฐ๋Šฅ์— input์— ์ ํžŒ ๋‚ด์šฉ๋“ค์„ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค.

  • req.body : ํผ์œผ๋กœ ์ „์†กํ•œ ๋ฐ์ดํ„ฐ
    { title : "์•ˆ๋…•", content : "๋ฐ˜๊ฐ€์›Œ" }

MongoDB์— ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๋Š” ๋ฒ•

import { connectDB } from "@/util/database";

export default async function handler(req, res) {
  if (req.method === "POST") {
    if (req.body.title === "" || req.body.content === "")
      return res.status(500).json("๋‚ด์šฉ์„ ๋ชจ๋‘ ์ ์–ด์ฃผ์„ธ์š”.");
    try {
      const db = (await connectDB).db("forum");
      const result = await db.collection("post").insertOne(req.body);
      return res.redirect(302, "/list");
    } catch (error) {
      return res.status(400).json("Error");
    }
  }
}
  • inserOne()์„ ์‚ฌ์šฉํ•˜์—ฌ document๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์œ ์ €์—๊ฒŒ ๋ฉ”์‹œ์ง€๋‚˜ ๋ฐ์ดํ„ฐ ๋ณด๋‚ผ ๋•Œ๋Š” json() ์‚ฌ์šฉ
  • redirect๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๊ณต์‹œ ํ•ด๋‹น URL๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ๊ณต๋ถ€

0๊ฐœ์˜ ๋Œ“๊ธ€