ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

๐Ÿ“ก Next.js App Router ๋ฐ์ดํ„ฐ ํŒจ์นญ ์™„๋ฒฝ ๊ฐ€์ด๋“œ

Next.js App Router๋Š” ์„œ๋ฒ„/ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ํŒจ์นญํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ fetch, ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ ๊ธฐ๋ฐ˜ ์š”์ฒญ, ๊ทธ๋ฆฌ๊ณ  ๋กœ๋”ฉ ๊ด€๋ฆฌ๊นŒ์ง€ ์ „๋ฐ˜์ ์ธ ์‚ฌ์šฉ๋ฒ•์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


โœ… ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ๋ฐ์ดํ„ฐ ํŒจ์นญ

Next.js App Router์—์„œ๋Š” ํŽ˜์ด์ง€์™€ ๋ ˆ์ด์•„์›ƒ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

๐Ÿ”น fetch ์‚ฌ์šฉ ์˜ˆ์‹œ

// app/posts/page.tsx
export default async function Page() {
  const res = await fetch('https://api.example.com/posts', {
    cache: 'no-store', // ๋˜๋Š” next: { revalidate: 60 }
  });
  const posts = await res.json();

  return (


{posts.map((post) => (-   {post.title}
))}

  );
}
  • cache: 'no-store': ๋งค ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ ๊ฐ€์ ธ์˜ด
  • next: { revalidate: 60 }: 60์ดˆ ๊ฐ„ ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ (ISR)

โœ… ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ๋ฐ์ดํ„ฐ ํŒจ์นญ

ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ('use client')๋Š” useEffect, fetch, SWR ๋“ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

๐Ÿ”น ํด๋ผ์ด์–ธํŠธ fetch + useEffect

'use client';
import { useEffect, useState } from 'react';

export default function ClientPosts() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch('/api/posts')
      .then(res => res.json())
      .then(data => setPosts(data));
  }, []);

  return (
    <ul>
      {posts.map((p) => (
        <li key={p.id}>{p.title}</li>
      ))}
    </ul>
  );
}

๐Ÿ”น SWR ์‚ฌ์šฉ (๋น„๋™๊ธฐ ์บ์‹ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)

'use client';
import useSWR from 'swr';

const fetcher = url => fetch(url).then(res => res.json());

export default function Profile() {
  const { data, error, isLoading } = useSWR('/api/profile', fetcher);

  if (isLoading) return <div>๋กœ๋”ฉ ์ค‘...</div>;
  if (error) return <div>์—๋Ÿฌ ๋ฐœ์ƒ</div>;

  return <h1>{data.name}</h1>;
}
  • ์ž๋™ ์บ์‹ฑ ๋ฐ ์žฌ๊ฒ€์ฆ ์ง€์›
  • ์ „์—ญ ์ƒํƒœ ๊ณต์œ  ๊ฐ€๋Šฅ

โœ… ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ UX ๊ฐœ์„ 

App Router๋Š” ๋กœ๋”ฉ ์ƒํƒœ ์ „์šฉ ์ปดํฌ๋„ŒํŠธ์™€ Suspense๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์‹œ UX๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”น loading.tsx ์‚ฌ์šฉ

// app/posts/loading.tsx
export default function Loading() {
  return <p>๊ฒŒ์‹œ๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...</p>;
}

ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์˜ page.tsx๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ ์ž๋™์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ”น Suspense๋กœ ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ ๊ฐ์‹ธ๊ธฐ

๋ฐ˜์‘ํ˜•
// app/posts/page.tsx
import { Suspense } from 'react';
import PostList from './PostList';

export default function Page() {
  return (
    <Suspense fallback={<p>๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...</p>}>
      <PostList />
    </Suspense>
  );
}

PostList๊ฐ€ async ์ปดํฌ๋„ŒํŠธ๋ผ๋ฉด Suspense๋กœ ๊ฐ์‹ธ๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.


โœ… ์‹ค๋ฌด ํŒจํ„ด ์š”์•ฝ

ํŒจ์นญ ์œ„์น˜ ์‚ฌ์šฉ ๋ฐฉ์‹ ๊ถŒ์žฅ ์ƒํ™ฉ

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ fetch, DB ์ฟผ๋ฆฌ ๋ณด์•ˆ ๋ฐ์ดํ„ฐ, ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง
ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ useEffect + fetch ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ, ๋น„๋™๊ธฐ UI
ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ SWR / React Query ์บ์‹ฑ, ์ „์—ญ ๊ณต์œ , ์ž๋™ ๊ฐฑ์‹ 
์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ revalidate ์˜ต์…˜ ์ฃผ๊ธฐ์  ISR ์‚ฌ์šฉ ์‹œ

โœ… ๊ฒฐ๋ก 

  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ = ์•ˆ์ „ํ•˜๊ณ  ๋น ๋ฅธ ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ๋ Œ๋”๋ง
  • ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ = ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ ์ค‘์‹ฌ ์ฒ˜๋ฆฌ
  • SWR = ํด๋ผ์ด์–ธํŠธ ์บ์‹ฑ ์ตœ์ ํ™”
  • loading.tsx + Suspense = ๋ถ€๋“œ๋Ÿฌ์šด UX ์ œ๊ณต

Next.js App Router๋Š” ๋ฐ์ดํ„ฐ ํŒจ์นญ ๊ตฌ์กฐ๊ฐ€ ๋งค์šฐ ์œ ์—ฐํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ธฐ๋ณธ ๋™์ž‘ํ•˜๋˜, ํด๋ผ์ด์–ธํŠธ ์ „ํ™˜๋„ ์‰ฌ์šฐ๋ฏ€๋กœ ์ƒํ™ฉ์— ๋งž์ถฐ ์กฐํ•ฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.


 

Next.js, App Router, ๋ฐ์ดํ„ฐ ํŒจ์นญ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ, fetch, SWR, React Query, Suspense, UX ์ตœ์ ํ™”

โ€ป ์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค.
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2025/06   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
๊ธ€ ๋ณด๊ด€ํ•จ
๋ฐ˜์‘ํ˜•