SWR
은 데이터 로드에 강력한 기능을 제공하지만, 데이터를 받기 전까지 유저에게 빈 화면을 보여주게 된다. 클라이언트 사이드에서 로딩 페이지를 보여주지 않고, 데이터가 로드 되었을 시 한 번에 완전한 페이지를 보여주려고 할 때 getServerSideProps()
기능을 사용한다.
function Home({ data }) {
// Render data...
}
// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
return { props: { data } } // Pass data to the page via props
}
export default Page
SWR
을 구성할 때는 따로 api 폴더를 만들었지만, getServerSideProps
는 보여주고자 하는 페이지에 함께 작성한다. getServerSideProps
내에서 받고자 하는 데이터를 요청해 받은 data
를 리턴한다. 리턴된 data
를 Page
컴포넌트의 인자로 준다.
유저가 페이지에 접속하면 서버에서 필요한 데이터를 전부 받을 때까지 빈 화면을 보여주게 된다.
유저가 내용 없는 레이아웃을 보면서 데이터를 기다릴 필요가 없다는 장점이 있는 반면, 데이터베이스 등 데이터 제공 측면에서 에러가 발생했을 때 아무런 페이지를 보여주지 않는다는 단점이 있다.
장점을 활용하면서 단점을 해결하기 위해 SWR
을 함께 사용할 수 있다.
function Home() {
const { data } = useSWR("/api/url");
// Render data...
}
function Page({ data }) {
// SWR hooks inside the `SWRConfig` boundary will use those values.
return (
<SWRConfig value={{
fallback: {
"/api/url": { // reponse shape
ok:true,
user,
}
}
}}>
<Home />
</SWRConfig>
)
}
// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
return { props: { data } } // Pass data to the page via props
}
export default Page
메인 컴포넌트를 감싼 SWRConfig
의 fallback
프로퍼티에 SWR
에서 사용하는 api를 키로 부여하고, response의 형태를 알려준다.
무엇을 export default
하느냐에 따라 getServerSideProps
의 props
를 받는 컴포넌트가 달라진다. 만약 Home
을 한다면 props
는 Home
으로 향하고, Page
라면 Page
로 향한다.
Next.js
에서 사용하는 session 라이브러리인 iron-session
을 이용해 getServerSideProps
내에서 세션을 만들 수 있다.
npm add iron-session
좀 더 직관적이게 핸들러 함수를 만든다.
import { withIronSessionSsr } from "iron-session/next";
const cookieOptions = {
cookieName: "cookieName",
password: process.env.SESSION_PWD!,
};
export function withSsrSession(handler: any) {
return withIronSessionSsr(handler, cookieOptions);
}
핸들러를 사용해 session을 형성한다.
function Home() {
// Render data...
}
function Page({ data }) {
// SWR hooks inside the `SWRConfig` boundary will use those values.
return (
<SWRConfig value={{
fallback: {
"/api/url": { // reponse shape
ok:true,
user,
}
}
}}>
<Home />
</SWRConfig>
)
}
export const getServerSideProps = withSsrSession(async function ({
req,
}: NextPageContext) {
const user = req?.session.user,
return {
props: {
user,
},
};
}
export default Page
위 에러는 props의 데이터 타입을 json이 읽지 못했기 때문이다. json을 파싱해서 리턴한다.
export const getServerSideProps = withSsrSession(async function ({
req,
}: NextPageContext) {
const user = req?.session.user,
return {
props: {
user: JSON.parse(JSON.stringify(user)) ,
},
};
}
참고
노마드 코더 - 캐럿마켓 클론코딩
Next.js Docs - getServerSideProps
SWR Docs - Prerendering
Iron-Session - withIronSessionSsr
정보 감사합니다 getServerSideProps에서 iron-session에 있는 user 인식하게 하려고 하다가 들어왔어요!