next.js, react-query, firebase이 3가지 조합으로 sns와 같은 형태의 서비스 제작 연습을 하고 있으며, 이 과정에서 feed와 상세페이지 쪽에서 pre-render를 하는 과정을 정리하려 합니다.
next.js는서버사이드 렌더링(SSR), 정적 사이트 생성(SSG), 클라이언트 사이드 렌더링(CSR) 모두 지원하고 있습니다. 이중 SSR과 SSG를 사용해서 pre-render해보려 합니다.
getStaticProps
는 next.js
가 페이지를 빌드할 때 페이지에 필요한 데이터를 가져와서 props로 전달하는 역할을 수행합니다.
기본적인 사용 형태는 링크를 통해 확인하실 수 있습니다.
메인페이지에서 게시물의 리스트를 무한스크롤 방식을 통해 렌더하고 있는데, 이 부분에서 getStaticProps
를 사용해보려 합니다.
export const getStaticProps = async () => {
const queryClient = new QueryClient();
await queryClient.prefetchInfiniteQuery(PostKey.getPostList(), () => getPostList());
return {
props: {
dehydratedState: dehydrate(queryClient)
},
revalidate: 60
};
};
react-query
에 useInfiniteQuery
를 통해 무한스크롤을 처리해 주고 있었기에 prefetchInfiniteQuery
를 사용해주었습니다.
그런데 아래와 같은 오류가 발생하였습니다.
오류의 원인은 prefetchInfiniteQuery
에서 pageParams
의 초기값이 undefined
이기 때문에 직렬화할 수 없다 알려주고 있습니다.
해당 이슈에 대한 정보는 github
의 issue
에서 찾을 수 있었으며, 링크를 통해 확인할 수 있습니다.
dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient)))
JSON.parse
와 JSON.stringfy
를 사용해 undefined가 null로 변경되는 성질을 활용해 직렬화가 가능하도록 처리해 주었습니다.
적용후 깜빡거림이 없어진 모습입니다.
getStaticProps
를 통해 pre-render
를 해보았으나, 지금 진행하는 SNS와 같은 프로젝트의 경우 사용자가 많고, 실시간으로 새로운 게시물이 올라오기에 getStaticProps
의 사용이 적절한가에 대한 답변은 의문이지만 연습이기에 사용해 보았고, revalidate
를 지정해 어느정도 대응해 주었습니다.
현재 위에서 사용한 문법의 경우 next.js
v12의 문법입니다. 현재 v13의 경우 많은 부분에서 변동이 있었으며, fetch
를 이용해 pre-render
를 진행하고 있었습니다.
async function getData() {
const res = await fetch('https://api.example.com/...')
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
// Recommendation: handle errors
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data')
}
return res.json()
}
기본적인 형태는 위와 같으며, 함수의 이름또한 getStaticProps
등으로 강제할 필요가 없어졌습니다.
fetch('https://...', { next: { revalidate: 10 } })
위처럼 revalidate
를 이용해 getStaticProps
와 같은 효과를 낼 수 있으며,
fetch('https://...', { cache: 'no-store' })
no-store를 통해 getServerSideProps와 같은 효과를 낼 수 있습니다.
그 밖에도 기존에 페이지 단위에서 지원하던 pre-render
를 컴포넌트 단위에서도 지원하기 시작했으며, use client
명령어를 활용해 구분할 수 있게 되었습니다.
신규 프로젝트들은 v13을 많이 채택하는 것 같으나, 아직 v12로 만들어진 프로젝트가 많기에 이번 프로젝트는 v12로 연습해보고 다음 프로젝트는 v13을 사용해보려 합니다.