서버사이드 렌더링이란, 클라이언트 대신 서버에서 HTML 코드를 생성하고 반환하는 방식으로 웹페이지를 렌더링하는 방식이다.
이를 통해 초기 로딩 속도를 개선하고 SEO(Search Engine Optimization)에 유리한 웹페이지를 만들 수 있다.
getServerSideProps는 Next.js에서 사용되는 함수 중 하나로, 서버사이드 렌더링(Server-Side Rendering)을 지원하기 위해 제공되는 함수다.
getServerSideProps 함수는 페이지 컴포넌트에서 사용되며, 페이지가 요청되기 전에 먼저 서버에서 실행된다.
이 함수에서 반환하는 객체는 페이지 컴포넌트의 props로 전달되며, props는 페이지 컴포넌트에서 사용되는 데이터를 담고 있는 객체다.
getServerSideProps 함수는 비동기 함수로 작성해야 하며, 다양한 데이터 소스에서 데이터를 가져오거나 API를 호출할 수 있다.
이 함수에서 반환하는 데이터는 props에 포함되어, 페이지 컴포넌트에서 사용될 수 있다.
Firebase에서 데이터를 가져오는 부분을 getServerSideProps 함수에 빼고 나온 데이터를 Props로 페이지 컴포넌트(BoardDetailPage)에서 사용했다.
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 },
};
}
매우 유의미한 둘의 차이를 볼 수 있다.