[Next.js] Page Router - SSR

YeonjuΒ·2025λ…„ 2μ›” 15일

Next.js

λͺ©λ‘ 보기
8/10

πŸ“š SSR νŽ˜μ΄μ§€μ˜ μ‹€ν–‰ μˆœμ„œ

  1. https://www.~ νŽ˜μ΄μ§€ μš”μ²­μ΄ μ˜¨λ‹€.
  2. getServerSideProps ν•¨μˆ˜κ°€ μ‹€ν–‰λœλ‹€.
  3. νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈκ°€ μ‹€ν–‰λœλ‹€.

πŸ”¨ getServerSideProps

νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈλ³΄λ‹€ λ¨Όμ € μ‹€ν–‰λ˜μ–΄μ„œ, μ»΄ν¬λ„ŒνŠΈμ— ν•„μš”ν•œ 데이터 λΆˆλŸ¬μ˜€λŠ” ν•¨μˆ˜

export const getServerSideProps = () => {}

파일 내에 μ•½μ†λœ μ΄λ¦„μ˜ ν•¨μˆ˜ getServerSidePropsλ₯Ό λ§Œλ“€μ–΄ 내보내면 (export), ν•΄λ‹Ή νŽ˜μ΄μ§€λŠ” μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§ 방식이 μ μš©λœλ‹€.

πŸ’¬ μ„œλ²„μ—μ„œ 1번만 μ‹€ν–‰λœλ‹€.

  • console.log 같은 μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ„ 개발자 λ„κ΅¬μ—μ„œ 확인 λΆˆκ°€ / 터미널 λ‘œκ·Έμ—μ„œλ§Œ 확인 κ°€λŠ₯
  • λΈŒλΌμš°μ €μ—μ„œλ§Œ λ™μž‘ν•˜λŠ” window.location() 같은 μ½”λ“œ μž…λ ₯μ‹œ μ—λŸ¬ λ°œμƒ (undefined μ΄λ―€λ‘œ)

return

export const getServerSideProps = () => {
  const data = "..."

  return {
    props: {
      data,
    },
  };
};

λ°˜λ“œμ‹œ 단 ν•˜λ‚˜μ˜ ν”„λ‘œνΌν‹° propsλ₯Ό κ°€μ§€λŠ” 객체λ₯Ό λ¦¬ν„΄ν•΄μ•Όν•œλ‹€.


πŸ“ƒ νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈ

props

export default function Home(props: any) {
 ...

λ¦¬ν„΄ν•œ κ°μ²΄λŠ” νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈμ˜ Props둜 λ°›λŠ”λ‹€.

πŸ“Œ InferGetServerSidePropsType νƒ€μž…

getServerSideProps의 λ°˜ν™˜κ°’ νƒ€μž…μ„ μžλ™μœΌλ‘œ μΆ”λ‘ ν•˜λŠ” νƒ€μž…

export default function Home(props: InferGetServerSidePropsType<typeof getServerSideProps>) {
...

πŸ’¬ μ„œλ²„, λΈŒλΌμš°μ €μ—μ„œ 각각 1λ²ˆμ”©, 총 2번 μ‹€ν–‰λœλ‹€.

export default function Home({ data }: any) {
  console.log(data);
  ...
  1. 사전 λ Œλ”λ§ (μ„œλ²„) - 터미널 λ‘œκ·Έμ— data 좜λ ₯
  2. μˆ˜ν™” (λΈŒλΌμš°μ €) - 개발자 도ꡬ console에 data 좜λ ₯

λ”°λΌμ„œ 아무 쑰건 μ—†μ–΄ window 같은 κ±° μ‚¬μš©μ‹œ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

λΈŒλΌμš°μ €μ—μ„œλ§Œ λ™μž‘ν•˜λŠ” μ½”λ“œ μž‘μ„±ν•˜κΈ°

1. useEffect

export default function Home({ data }: any) {
  useEffect(() => {
    console.log(window);
  }, []);

λ™μž‘ μ‹œμ μ΄ μ»΄ν¬λ„ŒνŠΈ 마운트 μ΄ν›„μ΄λ―€λ‘œ λΈŒλΌμš°μ €μ—μ„œλ§Œ λ™μž‘ν•œλ‹€.


πŸ’» κΈ°λŠ₯ κ΅¬ν˜„ν•˜κΈ°

fetch

import { BookData } from "@/types";

export default async function fetchBooks(): Promise<BookData[]> {
  const url = `http://localhost:12345/book`;

  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error();
    }
    return await response.json();
  } catch (err) {
    console.error(err);
    return [];
  }
}

fetch(), .json() 등이 λΉ„λ™κΈ°λ‘œ μž‘λ™ν•˜λ―€λ‘œ await μ‚¬μš©
await μ‚¬μš©ν–ˆμœΌλ―€λ‘œ ν•¨μˆ˜μ— async μΆ”κ°€

ν™•μž₯ν•˜κΈ°

export default async function fetchBooks(q?: string): Promise<BookData[]> {
  let url = `http://localhost:12345/book`;

  if (q) {
    url += `/search?q=${q}`;
  }
  ...

쿼리 qκ°€ μžˆλŠ” κ²½μš°μ—λ§Œ /search?q=${q}λ₯Ό url에 μΆ”κ°€ν•˜κΈ°

getServerSideProps

export const getServerSideProps = async () => {
  const allBooks = await fetchBooks();
  const recoBooks = await fetchRandomBooks();
  
  return {
    props: {
      allBooks,
      recoBooks,
    },
  };
};

fetchBooks() μ™„λ£Œ ν›„ β†’ fetchRandomBooks() μ‹€ν–‰
총 μ‹€ν–‰ μ‹œκ°„ = 두 ν•¨μˆ˜ μ‹€ν–‰ μ‹œκ°„μ˜ ν•©

λ”°λΌμ„œ fetchλ₯Ό 2번 이상 ν•˜λŠ” κ²½μš°μ—λŠ” μœ„μ™€ 같이 직렬둜 μ²˜λ¦¬ν•˜λŠ” 것은 λΉ„νš¨μœ¨μ μ΄λ‹€.

πŸ’‘ 병렬 처리

Promise.all() : 비동기 ν•¨μˆ˜ μ—¬λŸ¬ 개λ₯Ό λ³‘λ ¬λ‘œ μ‹€ν–‰ν•˜μ—¬, λͺ¨λ“  μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦° ν›„ ν•œκΊΌλ²ˆμ— κ²°κ³Όλ₯Ό λ°˜ν™˜ν•œλ‹€. κ°œλ³„ ν•¨μˆ˜κ°€ await 없이 μ‹€ν–‰λ˜λ―€λ‘œ, 전체 μ‹€ν–‰ 속도가 λ‹¨μΆ•λœλ‹€.

export const getServerSideProps = async () => {
  const [allBooks, recoBooks] = await Promise.all([
    fetchBooks(),
    fetchRandomBooks(),
  ]);

  return {
    props: {
      allBooks,
      recoBooks,
    },
  };
};

두 ν•¨μˆ˜ fetchBooks() fetchRandomBooks() λ™μ‹œμ— μ‹€ν–‰
μ΅œλŒ€ μ‹€ν–‰ μ‹œκ°„ = 두 ν•¨μˆ˜ 쀑 더 였래 κ±Έλ¦¬λŠ” 것

πŸ’‘ context 객체

  • getServerSideProps ν•¨μˆ˜μ—μ„œ Next.jsκ°€ μ œκ³΅ν•˜λŠ” μš”μ²­ κ΄€λ ¨ 정보가 λ‹΄κΈ΄ 객체

  • getServerSideProps ν•¨μˆ˜μ˜ 첫 번째 λ§€κ°œλ³€μˆ˜μ΄λ©°, νƒ€μž…μ΄ GetServerSidePropsContext이닀.

export const getServerSideProps = async (context: GetServerSidePropsContext) => {
  const q = context.query.q;     // 쿼리값 κ°€μ Έμ˜€κΈ°
  const id = context.params!.id; // νŒŒλΌλ―Έν„°μ˜ id 뢈러였기
  ...

context.query β†’ 쿼리 슀트링 (ex: ?q=book β†’ context.query.q)
context.params β†’ 동적 경둜 νŒŒλΌλ―Έν„° (ex: /book/[id] β†’ context.params.id)
context.req β†’ μš”μ²­ 객체 (Request Object) (headers, cookies 확인 κ°€λŠ₯)
context.res β†’ 응닡 객체 (Response Object) (μΊμ‹œ 컨트둀 μ„€μ • κ°€λŠ₯)

profile
ν–„μŠ€ν„°μ™€ κ°œλ°œμ„ μ’‹μ•„ν•©λ‹ˆλ‹€.

0개의 λŒ“κΈ€