nextJS는 서버사이드 렌더링을 하는데 각 페이지마다 사전에 불러와야할 데이터가 있다.
react나 vue에서는 useEffect 나 created 를 이용하여 페이지에 접근하기 전에 데이터를 받아온다. next는 getInitialProps를 이용하여 fetching 작업을 진행한다.
사용 하고 싶은 컴포넌트 외부에 getInitialProps 함수를 선언하여 사용한다.
import { useRouter } from "next/router";
import posts from "../posts.json";
const Posts = (props: { post: { title: string; content: string } }) => {
const router = useRouter();
return (
<>
<h1>{props.post.title}</h1>
<h1>{props.post.content}</h1>
</>
);
};
Posts.getInitialProps = context => {
return {
post: posts[context.query.id]
};
};
export default Posts;
getInitialProps 내부에는 context, component등 여러 객체들이 있다.
위의 예시는 query.id에 접근하여 담아주는 것을 하였다.
렌더링때 거치는 순서는 _app => page component이다.
만약 _app에 getInitialProps를 정의했다면, 하위 컴포넌트에서는 getInitialProps는가 실행되지 않는다.
하위 컴포넌트에서도 사용하려면 추가 작업이 필요하다.
// src/_app.tsx
import "./globals.css";
function MyApp({ Component, pageProps }) {
return <Component ponent {...pageProps} />;
}
MyApp.getInitialProps = async ({ Component, ctx }) => {
let pageProps = {};
// 하위 컴포넌트에 getInitialProps가 있다면 추가 (각 개별 컴포넌트에서 사용할 값 추가)
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
// _app에서 props 추가 (모든 컴포넌트에서 공통적으로 사용할 값 추가)
pageProps = { ...pageProps, posttt: { title: 11111, content: 3333 } };
return { pageProps };
};
export default MyApp;
서버에서 실행되기 때문에 브ㅏㄹ우저 api (setTimeout, window.xx ,document.xx)는 실행하면 안된다.
Next v9 이상에서는 getInitialProps 대신 getStaticProps, getStaticPaths, getServerSideProps을 사용하도록 가이드 한다.
좀더 상세하게 함수들을 나눈것 같다.
getStaticProps는 빌드 시 데이터를 패치하는 함수이다.
function BlogPost({ post }) {
return (
<div>
<h1> {post.title} </h1>
<div> {post.content} </div>
</div>
)
}
export async function getStaticProps() {
const res = await fetch('https://.../posts/1')
const post = await res.json()
return {
props: {
post,
}
}
}
export default BlogPost
이런식으로 사용하는데 바로 함수를 생성하면서 사용하는 것 같다.
props로 post값을 내려주었고 blogPost 컴포넌트에서 post값을 받아서 사용했다.
데이터에 따라 pre-rendering할 페이지의 동적경로를 지정하는 함수이다.
export async function getStaticPaths() {
return {
paths: [
{ params: { ... } }
],
fallback: ...
};
}
이런 형태로 사용되는데 paths 값을 getStaticProps로 리턴해준다.
이전에 설명했던 것처럼 pages에 각각 동적 컴포넌트를 생성할수 있다.
동적 경로마다 패스를 지정해서 넘겨주는 것이다.
동적 컴포넌트에서 getStaticPaths, getStaticProps로 같이 쓰인다.
getStaticPaths 함수로 동적 컴포넌트 명으로 값을 내려주고
getStaticProps 에서 받은 값으로 props를 사용해주는 것이다.
paths에서 리턴되지 않은 경로에 대해서 어떻게 처리할지 정하는 옵션이다.
function BlogPost({ post }) {
return (
<div>
<h1> {post.title} </h1>
<div> {post.content} </div>
</div>
)
}
export async function getStaticPaths() {
const res = await fetch('http://.../posts')
const posts = await res.json()
const paths = posts.map((post) => ({
params: { id: post.id },
}))
return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
return {
props: {
post,
}
}
}
export default BlogPost
위의 예시처럼 getStaticPaths 에서 각 값들을 다 받은다음에 map함수로 params별로 나눠주었다 그리고 각 path에 맞는 데이터들을 getStaticProps를 통해서 뿌려주는 것이다.
이름만 봐도 알듯이 서버 사이드 렌더링을 위한 함수이다.
getStaticProps 처럼 컴포넌트에 props를 넘겨준다는 공통점이 있지만, 빌드 시가 아닌 매 request마다 실행된다는 차이점이 있다.
export async function getServerSideProps(context) {
return {
props: {},
}
}
이렇게 사용하며 추가적으로 미들웨어인 ‘req’가 제공된다.