⚡ getServerSideProps 처럼 Next.js 에서 약속된 이름의 함수를 만들어서 export하면 해당 페이지는 이제 SSR로 동작하도록 자동 설정됨
export const getServerSideProps = () => {
🟦 getServerSideProps는 밑 Home 페이지 컴포넌트보다 먼저 실행됨.
🟦 컴포넌트에 필요한 데이터를 불러오는 함수
return { // 반드시 props라는 개체 프로퍼티를 포함하는 하나의 객체 return
props: {
data,
},
}
}
//{data}
export default function Home(props: InferGetServerSidePropsType<typeof getServerSideProps>) {
📝 이 페이지도 두번 실행됨. 서버에서 한번 실행 -> 브라우저에서 한번 실행
📝 사전렌더링위해 서버에서 컴포넌트 실행 - 터미널에 hi 출력
📝 하이드레이션 과정에서 한번 더 컴포넌트 실행 - 콘솔에 hi 출력됨
console.log('hi')
// window.location ; -> 이런 코드 쓰면 서버에서 실행될때 오류뜸
🔍 해결 -> useEffect 처럼 브라우저에서 실행되는 코드 안에 쓰면 된다
export const getStaticProps = async () => {
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
])
return {
props: { allBooks, recoBooks },
}
}
export default function Home({
allBooks,
recoBooks,
}: InferGetStaticPropsType<typeof getStaticProps>) {
/book/[id]
처럼 동적 경로를 갖는 페이지에 SSG를 적용하려면 반드시 사전 렌더링 진행되기 전에 이 페이지에 존재할수있는 모든 경로들을 직접 설정하는 작업을 먼저 해야한다. getStaticPaths 를 사용!
getStaticPaths = == 1. 경로 설정
getStaticProps = == 2. 사전렌더링
빌드 타임에 사전에 생성해 두지 않았었던 페이지까지 사용자에게 제공
기존 경로에 없던 페이지는 처음에 SSR 방식처럼 서버사이드에서 사전렌더링 하느라 느릴수도있지만 그 이후 요청에는 Next 서버에 저장되어서 빠르게 렌더링
위에 blocking은 서버사이드에서 사전렌더링될때 페이지 데이터가 크다면 로딩시간이길어질수있다는 단점이있는데, 이를 보완한게 true
Props가 없는 페이지: getStaticProps로부터 받은 데이터가 없는 페이지, 즉 아무런 데이터가 없음. 사용자는 긴 로딩시간 대신 일단 페이지라도 먼저 볼 수 있다 = fallback 상태
fallback 상태 : 페이지 컴포넌트가 아직 서버로 부터 테이터를 전달 받지 못한 상태
사전 렌더링 방식이 SSG든 SSR이든 요청이들어올때마다 계속해서 새롭게 페이지를 사전 렌더링 한다. 그래서 SSG 가 제대로 작동하는지 보려면 빌드 후 실제 프로덕션 모드에서 실행을 시켜보아야한다.
가장 강력한 사전 렌더링 방식
단순히 그냥 SSG 방식으로 생성된 정적 페이지를 일정 시간을 주기로 다시 생성하는 기술
👆 기존 ssg의 방식 - 최신 데이터 반영 어려움
시간 기반 ISR - 특정 시간 이후에 정적으로 생성된 페이지를 다시 새롭게 재생성하도록 설정
export const getStaticProps = async () => {
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
])
return {
props: { allBooks, recoBooks },
🌟revalidate: 3, => 3초 주기로 업데이트 되게🌟
}
}
일단 위에 처럼 시간 기반 ISR 페이지가 사용될 수 없는 페이지는 매우많음
ex. 게시글 페이지 처럼 사용자의 행동에 따라 변하는 페이지
=> 요청 기반 ISR 페이지를 사용하자! 매우많이 사용됨
API Routes를 통해서 Revalidate 요청을 받으면 특정페이지를 다시 ssg 방식으로 재생성 하게끔
api/revalidate.ts
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
await res.revalidate('/') // index페이지 경로를 revalidate요청보낼거야
return res.json({ revalidate: true }) // revalidate 성공했다는 결과
} catch {
res.status(500).send('Revalidation failed')
}
}
이렇게 api route 코드를 작성해주고
index.ts
export const getStaticProps = async () => {
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
])
return {
props: { allBooks, recoBooks },
}
}
...
위 코드는 일반 ssg 코드랑 같지만
http://localhost:3000/api/revalidate
로 접속하면
페이지가 다시 재생성 되는걸 확인할 수 있다