Next.js SSR 해보기

IT공부중·2020년 2월 19일
1

Next

목록 보기
4/12
post-thumbnail

(이 글은 Next.js 9.3 이전 버전 기준으로 작성 되었습니다.)

저번에 하던 폴더에서 Next.js 공식문서를 보고 ssr을 해보려고 한다.

ssr(server-side-rendering)으로서 서버로부터 그려진 view를 받아오기 때문에 초기 구동 속도가 빠르고 seo 최적화 하기에 좋다.
자세한 설명들은 다른 글에 잘 작성되어 있는 것 같다!

저번에 했던 폴더에 SsrTest.js라는 페이지를 추가해서 시작했다!

그 다음 서버와의 통신을 하기 위해서 axios를 설치해주었다. next 공식 문서에서는
isomrphic-unfetch 라는 것을 사용하던데 처음보는거라 원래 좋아하던 axios를 사용했다.

npm install axios

그리고 나서 SsrTest.js에 코드를 작성해주었다.

import React from "react";
import axios from "axios";
import Link from 'next/link';

const SsrTest = ({ shows }) => {
  return (
    <div>
      <h1>Batman TV Shows</h1>
      <ul>
        {shows.map(show => (
          <li key={show.id}>
            <Link href="/d">
              <a>{show.name}</a>
            </Link>
          </li>
        ))}
      </ul>
    </div>
  );
};

SsrTest.getInitialProps = async () => {
    const res = await axios.get('https://api.tvmaze.com/search/shows?q=batman');
    const data = res.data;
    console.log(`Show data fetched. Count: ${data.length}`);

    return {
        shows : data.map(entry => entry.show)
    };
}
export default SsrTest;

next의 getInitialProps라는 함수를 이용하게 되면 서버쪽에서 데이터를 불러오고 그것을 클라이언트쪽으로 보내준다.
(처음 렌더링 될 때는 서버쪽에서 실행 되어 데이터를 불러오고, 페이지를 이동하는 routing을 할 때는 프론트에서 실행되는데 그래서 서버에서 실행 됐는지 아닌지 확인 하는 코드가 필요할 때가 있다.)

해당 코드는 'https://api.tvmaze.com/search/shows?q=batman' 에서 batman에 관련한 정보들을 가져오는 코드다.
그 정보들을 data에 담아서 return을 해주면 해당 Component의 props로 들어가게된다.

그런데 이렇게 해보니 안 되었다. 공식문서에서는 되는데 왜 난 안 되지 여러번 고민하다 나는 _app.js를 만들어 놨기 때문이란걸 알게됐다.
그래서 _app.js에 다음과 같은 코드를 추가하였다.

import React from "react";
import Link from "next/link";
const Test = ({ Component, pageProps }) => {
  return (
    <>
      <ul>
        <li>
          <Link href="/">
            <a>Home</a>
          </Link>
        </li>
        <li>
          <Link href="/[pagename]" as="/blog">
            <a>블로그</a>
          </Link>
        </li>
        <li>
          <Link href="/[pagename]" as="/cafe">
            <a>카페</a>
          </Link>
        </li>
        <li>
          <Link href="/ssrtest">
            <a>SSR</a>
          </Link>
        </li>
      </ul>
      <Component {...pageProps} />
    </>
  );
};

Test.getInitialProps = async context => {
  const {  ctx, Component } = context;
  console.log(ctx);
  console.dir(Component);
  let pageProps = {};
  if (Component.getInitialProps ) {
    pageProps = await Component.getInitialProps(ctx);
  }

  return { pageProps };
}

export default Test;

app.js가 모든 페이지들이 거쳐가는 곳이기 때문에 한번더 내려줄 필요가 있었나보다. 이 코드를 작성 안 했을 때는 계속 shows가 undefined가 떴었다.

코드를 보면 getInitialProps의 첫번째 인자로 context를 받는다. context에는 ctx랑 Component등이 들어있는데 ctx에는 나중에 리덕스 store 등도 담기게 되는것 같다.

context, ctx, Component는 각각 이런 값들을 가지고 있다!!

Component에 props들을 넘겨주기 위해 pageProps라는 변수를 만들고
만약 Component에 getIntialProps가 있으면 ctx를 인자로 실행시켜서 리턴값을 pageProps에 넣고 리턴을 해준다음
<Component {...pageProps}/>로 넣어주면 해당 컴포넌트에서 props로 사용 가능해진다!!.
(인자로 ctx를 넣으면 SsrText.js 같은 하위 컴포넌트에서 ctx.query 등으로 query 정보나 path들을 알 수 있다. 안 넣어도 됨!!)

이렇게 세팅을 해주고 나서 실행을 시킨다음 SSR 링크를 누르면 서버쪽에서 정보를 받아온다음에 클라이언트 쪽에 준다음 화면을 그려준다.

이제 새로고침을 눌러보면 이미 서버에 정보가 있기 때문에 console.log가 다시 찍히지 않는 것을 볼 수 있다. 서버에 정보가 있기 때문에 다시 불러올 필요가 없기 때문이다.
다른 링크들을 클릭 하고 다시 올 때는 다른 정보가 덮어져서 그런가 다시 console.log가 찍히는 것을 볼 수 있었다.

다음에는 동적 라우팅 + SSR해서 ctx로부터 query를 받아서 그 정보를 바탕으로 SSR하는 것을 해봐야겠다.

profile
4년차 프론트엔드 개발자 문건우입니다.

0개의 댓글