2022. 2. 3. 14:10ㆍReactJS/Next.js
Next.js에서는 사용자의 요청 혹은 Build Time에서 Data를 Fetching하고 배치시키기 위해 사용하는 함수가 있다.
(CSR React 딴에서 useEffect(ComponentDidMount)를 이용해 Data Fetching을 진행하여 데이터를 보여주는 것과 같다고 생각하면 된다.)
이에 대해 사용하는 방법과, 각자의 특성에 대해 설명하고자 한다.
getInitialProps
- 페이지를 SSR로 생성하며 Data fetching를 해야할 경우 사용된다.
function Page({ stars }) {
return <div>Next stars: {stars}</div>
}
Page.getInitialProps = async (ctx) => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const json = await res.json()
return { stars: json.stargazers_count }
}
export default Page
- 각 페이지에 Static Method로 구현된다.
- async function으로 구현 가능하다.
- 현재 Page 내 "stars"는 client로 보내지기전에 server에서 "stars"값을 받은 후에 보내진다.(SSR로 작동)
- ctx(Context) 인자는 아래와 같은 properties를 갖고 있다.
ctx.pathname - 현재 route 이름
ctx.query - URL의 Query string section
ctx.asPath - query를 포함한 실제 경로명 (브라우저에 보이는 주소값)
ctx.req - HTTP request object (server-side only)
ctx.res - HTTP response object (server-side only)
ctx.err - 렌더링 중 오류 발생 시 Error object
Next.js v9.3 이전 버전에서는 위 getInitialProps를 사용해야 한다.
하지만 Next.js v9.3 이후 버전에서는 SSG, SSR 분리를 위해 권장되지 않는다.
getStaticProps, getServerSideProps 사용을 권장하고 있다.
*주의*: _app에서 getInitialProps를 사용해 모든 페이지에서 사용할 공통 속성값을 지정할 수 있으나, 이럴 경우 자동 정적 최적화(Automatic Static Optimization)이 비활성화되어 모든 페이지가 서버 사이드 렌더링을 통해 제공된다.
*자동 정적 최적화 : 페이지를 정적 HTML로 인식하여 사전 렌더링을 진행 후 정적 최적화를 진행.
SSR 계산이 없기 떄문에 사용자에게 뿌려지는 Ultra Fest 로딩이다.
getInitalProps는 자식 component에는 사용할 수 없다.
위 작성한 바와 같이 Next는 SSR과 SSG를 분리하기 위해 아래 세개의 대체 API를 제공하고 있다.
getStaticProps, getStaticPath, getServerSideProps
아래에 나올 내용은 Next.js v9.3 이후 버전에서만 사용 가능하니 참고하여 보도록 하자.
getStaticProps(Next.js v9.3 이 후 사용 가능)
- 빌드 타임 때 정적으로 생성되는 값이다.
- 빌드 이 후 수정이 불가능하다.
- 사전 렌더링 방법중 SSG로 적용된다.
// 'pages/Blog.tsx'
function Blog({ posts }) {
...
}
export const getStaticProps = async (context) => {
const res = await fetch("...")
const posts = res.json()
if(!posts) {
return {
notFound: true
}
}
return {
props : {
posts
}
}
}
export default Blog
context 인자는 아래와 같은 properties를 갖고 있다.
- params - 동적 라우팅 페이지라면 라우트 파라미터 정보를 갖고 있다.
- req : HTTP request object (server-side only)
- res : HTTP response object (server-side only)
- query : Query String
- preview : Preview-mode 여부
- previewData : setPreviewData로 설정된 Data
리턴시에는 아래와 같은 Object 형식으로 리턴을 진행해야 한다.
- props(Optional, Object) : 해당 컴포넌트로 리턴할 데이터
- revalidate(Optional, Boolean | number) : 페이지 재생성이 발생할 수 있는 시간(sec), 기본값 : false, false 인 경우 다음 빌드때까지 페이지가 빌드된 상태로 캐싱 처리 된다.
- notFound(Optional, Boolean) : 404 status를 사용할 지 말지에 대한 여부 값이다.
빌드시에 데이터를 가져온 후 Contentful & Static한 HTML을 만든 후 제공되기 때문에 굉장히 빠른 속도로 페이지가 렌더링 된다.
유저의 요청 순간순간마다 데이터를 패치할 필요가 없는 데이터를 가진 페이지를 렌더링할 때 매우 유리하다.
[참고 : [Next.js] SSR(Server-Side-Rendering)과 SSG(Static-Site-Generation)의 차이 ]
getStaticPaths(Next.js v9.3 이 후 사용 가능)
- 빌드 타임 때 정적으로 렌더링할 경로를 설정한다.
- 이곳에 정의하지 않은 하위 경로는 접근해도 페이지가 나오지 않는다.(옵션으로 설정 가능하다.)
- 정적인 페이지를 만들 때 사용된다.
- String, Object, Array로 정적 경로를 설정할 수 있다.
- 페이지가 동적 라우팅을 사용하고, getStaticProps로 정적인 페이지를 만들 때 유용히 사용된다.
// 'pages/posts/[id].tsx'
function Post({ post }) {
...
}
export const getStaticPaths = async () => {
const res = await fetch("http://.../posts") // POST 정보를 전부 받아옴
const posts = res.json()
/**
응답 객체는 아래와 같다고 가정하자.
{
id: number,
title: string,
body: string
}
*/
const paths = posts.map((post) => ({
params: { id : post.id },
}))
return {
paths,
fallback: false
}
}
export const getStaticProps = async (context) => {
// 동적 라우팅으로 설정된 [id] 값을 가져와 정보를 가져온다.
const res = await fetch(`http://.../posts/${context.params.id}`)
const post = res.json()
if(!posts) {
return {
notFound: true
}
}
return {
props : {
post
}
}
}
export default Post
빌드타임 때 접근 가능한 post의 목록을 전부 불러온 후 접근 가능한 id 리스트를 만들어 경로를 지정해주는 방식이다.
만약 동적 라우팅이 위와 같이 1개만 진행되는 방식이 아니라, 여러개를 넣어야 한다거나 가변형으로 넣어야 할 경우에는 아래와 같이 작성해주면 된다.
// pages/b/[name]/[id].tsx
export const getStaticPaths = async () => {
// data fetching...
return {
paths: [{
params: {
"name": "y0ngha",
"id": 1234
}
}]
}
}
// pages/c/[...path].tsx
export const getStaticPaths = async () => {
// data fetching...
return {
paths:[{
params: {
"path": ["y0ngha", "1234", "5678"]
}
}]
}
}
// --> c/y0ngha, c/y0ngha/1234, c/y0ngha/1234/5678 전부 접근 가능
(참고 : 가변형 라우팅중 Optional하게 사용하기 위해서는 double bracket을 사용해야 한다.)
(참고자료 : [React] Next JS 동적 라우팅 / Dynamic Routing)
리턴시에는 아래와 같은 Object 형식으로 리턴을 진행해야 한다.
- paths(Object) : 빌드 타임 때 pre-render 진행 할 경로를 설정하면 된다.
- fallback(Boolean) : paths에 지정된 경로 외에 들어올 경우 404 status를 나타낼지 말지에 대한 여부다.
true로 설정될 경우 추 후 요청시 만들어주겠다는 의미를 갖고 있다.
빌드시 getStaticPaths에 지정된 paths를 pre-rendering 진행하게 되고, 이 과정에서 getStaticProps가 적용되어 데이터가 들어가는 방식이다.
이 후에 나올 getServerSideProps와는 같이 사용할 수 없다.
getServerSideProps(Next.js v9.3 이 후 사용 가능)
- 빌드 타임 때 데이터를 불러오지 않고, 사용자가 요청할 때 마다 데이터를 불러오는 방식이다.
- 사용자가 요청할 때 마다 데이터를 불러오니, 당연히 SSG 방식으로 렌더링을 진행하는것이 아닌 SSR 방식으로 렌더링을 진행한다.
- Server-side에서 실행되며 Browser(Client) 에서는 실행되지 않는다.
- 사용시 자동 정적 최적화가 일어나지 않는다.
function Page({ data }) {
...
}
export const getServerSideProps = async (context) => {
const res = await fetch(`https://.../data`)
const data = await res.json()
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
return { props: { data: data } }
}
export default Page
context 인자는 아래와 같은 properties를 갖고 있다.
- params - 동적 라우팅 페이지라면 라우트 파라미터 정보를 갖고 있다.
- req : HTTP request object (server-side only)
- res : HTTP response object (server-side only)
- query : Query String
- preview : Preview-mode 여부
- previewData : setPreviewData로 설정된 Data
리턴시에는 아래와 같은 Object 형식으로 리턴을 진행해야 한다.
- props(Optional, Object) : 해당 컴포넌트에 리턴하는 값
- redirect(Optional, Object) : 값 내부와 외부 리소스에 대해 redirection 허용
아래와 같은 Object로 리턴해주어야 한다.
- destination(String) : 이동 할 주소
- permanent(Boolean)
▶ true : 영구적 이동, 308 Status Code를 리턴한다.
▶ false : 임시적 이동, 308 Status Code를 리턴한다.
[ 참고 자료 : https://kinsta.com/knowledgebase/307-redirect/ ]
오래된 HTTP 클라이언트를 적절히 redirection 하기 위해선 permanent 대신 statusCode Properties를 사용해야할 수 있다.(공식문서) - notFound(Optional, Boolean) : 404 status를 사용할 지 말지에 대한 여부 값이다.
'ReactJS > Next.js' 카테고리의 다른 글
[Next.js] SSR(Server-Side-Rendering) 과 SSG(Static-Site-Generation) 의 차이 (0) | 2022.02.02 |
---|---|
[Next.js] React SSR 프레임워크 Next.js 알아보기 (0) | 2022.02.02 |