Next.js) getServerSideProps를 사용해보자.. feat. Firebase

준영·2023년 3월 11일
2

Next.js를 써보자..

목록 보기
1/1
post-thumbnail

SSR(서버사이드 렌더링)이란?

서버사이드 렌더링이란, 클라이언트 대신 서버에서 HTML 코드를 생성하고 반환하는 방식으로 웹페이지를 렌더링하는 방식이다.
이를 통해 초기 로딩 속도를 개선하고 SEO(Search Engine Optimization)에 유리한 웹페이지를 만들 수 있다.


getServerSideProps란?

getServerSideProps는 Next.js에서 사용되는 함수 중 하나로, 서버사이드 렌더링(Server-Side Rendering)을 지원하기 위해 제공되는 함수다.
getServerSideProps 함수는 페이지 컴포넌트에서 사용되며, 페이지가 요청되기 전에 먼저 서버에서 실행된다.
이 함수에서 반환하는 객체는 페이지 컴포넌트의 props로 전달되며, props는 페이지 컴포넌트에서 사용되는 데이터를 담고 있는 객체다.
getServerSideProps 함수는 비동기 함수로 작성해야 하며, 다양한 데이터 소스에서 데이터를 가져오거나 API를 호출할 수 있다.
이 함수에서 반환하는 데이터는 props에 포함되어, 페이지 컴포넌트에서 사용될 수 있다.


사용하기

Firebase에서 데이터를 가져오는 부분을 getServerSideProps 함수에 빼고 나온 데이터를 Props로 페이지 컴포넌트(BoardDetailPage)에서 사용했다.

Firebase에서 넘겨받는 timestamp 날짜를 넘기려고 하니까 에러가난다.

getServerSideProps 함수 내에서 생성한 Date 객체는 JavaScript에서 객체이므로, JSON 형식으로 직렬화될 수 없다. 따라서 Date 객체를 직접 props로 전달하면 다음과 같은 에러가 발생한다.
그래서 나는 새로운 객체를 생성하여 date를 받을 때 변환을 해서 넣었고, 그 데이터를 props로 넘겨 주었다.

import styled from "@emotion/styled";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import dynamic from "next/dynamic";
// firebase
import { collection, getDocs, where } from "firebase/firestore";
import { doc, getDoc, query as fireQuery } from "@firebase/firestore";
import { firebaseDb } from "../../../../firebase.config";
import Main from "../../../components/Main/Main";

const BoardViewer = dynamic(
  () => import("../../../components/Main/Board/BoardViewer/BoardViewer"),
  { ssr: false }
);

export default function BoardDetailPage({ boardData }) {
  console.log("get server side props data: ", boardData);
  const router = useRouter();

  return (
    <Wrapper>
      {/* board detail component */}
      <ContentBox>
        <BoardViewer boardData={boardData} />
      </ContentBox>
      {/* boards list component */}
      <Main />
    </Wrapper>
  );
}

// 서버에서 넘겨줄 데이터입니다~~~~
export async function getServerSideProps({ query }) {
  let data = {};

  const urlParams = query.boardID;
  const boardType = urlParams.split("=")[0];
  const boardId = urlParams.split("=")[1];

  const docRef = doc(firebaseDb, boardType, boardId);
  const docSnap = await getDoc(docRef);

  if (docSnap.exists()) {
    data = docSnap.data();
  } else {
    console.log("No such document!");
  }

  let boardData = {
    // @ts-ignore
    title: data.title,
    // @ts-ignore
    content: data.content,
    // @ts-ignore
    tag: data.tag,
    // @ts-ignore
    name: data.name,
    // @ts-ignore
    id: data.id,
    // @ts-ignore
    email: data.email,
    // @ts-ignore
    timestamp: data.timestamp.toDate().toISOString().split("T")[0],
  };

  return {
    props: { boardData },
  };
}

결과

No SSR

Yes SSR

매우 유의미한 둘의 차이를 볼 수 있다.

profile
개인 이력, 포폴 관리 및 기술 블로그 사이트 👉 https://aimzero-web.vercel.app/

0개의 댓글