If you're using Next.js 9.3 or newer, we recommend that you use getStaticProps or getServerSideProps instead of getInitialProps.
9.3 부터는 아래와 같이 getInitialProps가 3개로 세분화 되었습니다. SSR인지, 단순한 정적 렌더인지를 구분할 수 있게 되었습니다.
이 부분은 다른 포스트에서 다뤄보도록하겠습니다. 현재 getInitialProps가 작동을 안하는 건 아니라서 getInitialProps도 알아두면 좋습니다.
https://darrengwon.tistory.com/744
- getStaticProps : 빌드 타임 때 data fetch
- getStaticPaths : data에 기반하여 pre-render할 동적 라우팅을 적어주어라.
- getServerSideProps: 각각의 요청마다 data를 fetch한다.
9 버전부터 pages/_app.js에 getInitialProps를 사용하지 않아도 되게 되었습니다.
관련 공식문서는 아래에서 살펴볼 수 있습니다.
https://nextjs.org/docs/upgrading#check-your-custom--pages_appjs
getInitialProps
getInitialProps enables server-side rendering in a page and allows you to do initial data population, it means sending the page with the data already populated from the server. This is especially useful for SEO.
즉, 페이지를 처음 로드할 때 JS로 렌더하기 이전의 텅빈 div를 보게 되는 게 아니라 렌더 이전의 데이터 조작이 가능해져 결과적으로 SSR을 구현하게 되는 거네요. getInitialProps가 SSR이라고 거칠게 요약할 수 있겠습니다.
주의할 점은 순간 nextjs의 automatic static optimization이 불가능해집니다.
server.js에서 특정 페이지를 렌더할 때 props를 아래와 같이 전달한 바가 있다.
그런데 해당 컴포넌트에 전달한 값 {id: req.params.id}는 어떻게 받아서 사용해야 할까?
(Next 9 이후 동적 라우팅이 가능해지면서 아래와 같은 코드는 필요 없어졌습니다.)
... 생략
app.prepare().then(() => {
const server = express();
server.get('/user/:id', (req, res) => {
// 다 좋은데 { id: req.params.id } 이거 어떻게 쓰나요?
return app.render(req, res, '/user', { id: req.params.id });
});
... 생략
});
해당 값을 /user에서 사용하기 위해서는 getInitialProps을 사용하면 된다.
동적 라우팅을 사용해도 getInitailProps를 사용하면 됩니다.
_app.js getInitialProps
이 메서드를 사용하기 위해서는 사전작업으로 모든 페이지 컴포넌트의 부모 격인 pages/_app.js에서 세부 컴포넌트로 해당 정보를 내려줘야 합니다.
보통 _app.js는 Component를 자체로 렌더하고 pageProps를 직접 풀어주는 형태를 가졌습니다.
function MyApp({ Component, pageProps }) {
return (
<>
<Head>
<title>Next!</title>
</Head>
<AppLayout>
<Component {...pageProps} />
</AppLayout>
</>
);
}
최상단 컴포넌트 역할을 하는 MyApp의 getInitialProps 메서드를 통해서 ctx를 세부 컴포넌트의 context로 넣어주겠습니다. 또, return한 값은 getInitialProps를 호출한 컴포넌트(여기서는 MyApp)의 props로 들어가게 됩니다.
MyApp.getInitialProps = async (context) => {
const { ctx, Component } = context;
let pageProps = {};
if (Component.getInitialProps) {
// Component의 context로 ctx를 넣어주자
pageProps = await Component.getInitialProps(ctx);
}
// return한 값은 해당 컴포넌트의 props로 들어가게 됩니다.
return { pageProps };
};
세부 컴포넌트 getInitialProps
세부 컴포넌트에는 getInitialProps를 통해 _app.js에서 넘겨준 ctx를 사용하면 됩니다.
보통 redux로 dispatch를 해서 정보를 가져오는 등의 처리를 합니다. getInitialProps
역시 다시 강조하자면 getInitialProps가 return한 값은 해당 컴포넌트의 props로 들어가게 됩니다.
// id props는 getInitialProps를 통해 받은 props입니다.
const User = ({id}) => {
const { mainPosts } = useSelector(state => state.post);
const { userInfo } = useSelector(state => state.user);
return (
...생략
);
};
// context는 _app.js를 통해 Component.getInitialProps(ctx);로 받은 값입니다.
User.getInitialProps = async (context) => {
// context에는 req, res, query, pathname, asPath, store 등이 있습니다.
// store는 우리가 넣어준 redux store를 의미합니다.
// _app.js에서 넘겨준 ctx가 context로 들어온다.
// 여기서 프론트 서버로 부터 넘겨 받은 값을 사용하면 된다.
const id = parseInt(context.query.id, 10);
// 여기서는 redux를 이용해서 자동적으로 action을 날렸다.
context.store.dispatch({
type: LOAD_USER_REQUEST,
data: id,
});
context.store.dispatch({
type: LOAD_USER_POSTS_REQUEST,
data: id,
});
// return한 값은 해당 컴포넌트의 props로 들어가게 됩니다.
return { id };
};
참고한 글)
https://yceffort.kr/2020/03/nextjs-02-data-fetching/
'React, Next, Redux > ▲ Next.js' 카테고리의 다른 글
next 다이나믹 라우팅과 우선순위 (0) | 2020.08.16 |
---|---|
Next.js 프로젝트의 구조와 Data Fetching 플로우 (0) | 2020.08.15 |
Next에 Redux 설치하기 + next-redux-wrapper (1) | 2020.06.27 |
express로 Next 커스텀 프론트 서버 구축하기 (0) | 2020.06.25 |
next/link, head, router, dynamic, error, image (0) | 2020.06.24 |