getServerSideProps 구성하기

yonghee·2022년 4월 27일

Next.js는 기본적으로 SSG방식이 default 값으로 정해져 있다. 이 말은 즉 SSR 방식을 사용하려면 따로 지정을 해야한다는 것이다.

적용방법 getServerSideProps


이와 같이 공식문서에 나와있다.

export async function getServerSideProps({}: GetServerSideProps) {
      const { results } = await ( 
        await fetch(`http://localhost:3000/api/movies`)
        ).json();
      return {
        props: {
          results,
        }, 
      };
}

함수명은 반드시 getServerSideProps로 해야하며 props 안에 키값으로 우리가 원하는 데이터값을 넣으면 된다.

getServerSideProps 사용하여 데이터 값을 넣은 다음은?

이제 getServerSideProps은 서버에서 실행 될 것이고 넣은 값을 활용을 해야 한다 server side를 통해 props를 보낼수 있다.

export default function Home({ results }: InferGetServerSidePropsType<GetServerSideProps>) {
  const router = useRouter();
  const onClick = (id:number, title:string) => {
    router.push(`/movies/${title}/${id}`  
    //   {
    //   pathname: `/movies/${id}`,
    //   query: {
    //     title,
    //   },
    // },
    );
  }
  // const [movies, setMovies] = useState<SetData[]>([])
  // useEffect(() => {
  //   (async () => {
  //     const { results } = await 
  //      (await fetch(`/api/movies`)).json();
  //     setMovies(results);
  //   })(); // ---> aysnc 부분이 익명 함수(재사용 불가)로 작성되었고, 익명 함수는 즉시 실행해야 하기 때문에 ()를 이용해 익명 함수를 바로 호출하는 것
  // } ,[]) 
    return ( 
        <>
        <div className='container' >
          <Seo title="Home"/> 
          {/* {movies.length === 0 && <h1>Loading...</h1>} */}
          {results?.map((movie: SetData) => (
          <div 
            onClick={() => onClick(movie.id, movie.original_title)} 
            className="movie" 
            key={movie.id}
          >
            <img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} />
            <h4>
              <Link href={`https://image/${movie.original_title}/${movie.id}`}
                // href={{
                //   pathname: `/movies/${movie.id}`,
                //   query: {
                //     title: movie.original_title,
                //   },
                // }}
                // as={`/movies/${movie.id}`}
              >
                <a>{movie.original_title}</a>
              </Link>
            </h4>                    
          </div>   
          ))}

SSR를 구현하는데 있어서 pageProps가 필요한 이유(SSR의 과정)

import { AppProps } from 'next/app'; 
import Layout from '../components/Layout';
import "../styles/globals.css";

export default function MyApp({ Component, pageProps }:AppProps) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

SSR를 구현하는데 있어서 pageProps가 필요한 이유는 우리가 페이지로 갈 때 Next.js가 Home을 받아서 render하기 위해 <Component {...pageProps} /> 이곳에 넣을 것이고 getServerSideProps함수를 호출 할 것이다.

export async function getServerSideProps({}: GetServerSideProps) {
      const { results } = await ( 
        await fetch(`http://localhost:3000/api/movies`)
        ).json();
      return {
        props: {
          results,
        }, 
      };
}

그러면 Next.js는 SSR을 사용하게 될 것이라는 것을 알게 되고
API 데이터를 받아오고 그 이후에 props 키값으로 데이터를 return하면 그 다음 Next.js가 그 props를 <Component {...pageProps} /> {...pageProps}에 넣을 것이다.
그리고 최종적으로 이렇게 결과로 나오는 것이다.

export default function Home({ results }: InferGetServerSidePropsType<GetServerSideProps>) { 
---생략-----
}

중요한 것은 getServerSideProps 함수는 오직 server에서만 실행 된다는 것이다

이렇게 SSR을 사용하니 useState useEffect없이 화면을 구성할 수 있다는 점이 놀라웠고 굉장히 편하게 느껴졌다. 하지만 그 뜻은 loading 화면을 따로 구성하지 않는 다는것을 뜻하기 때문에 개발 환경에 따라 선택해서 사용해야 될 것 같다.

profile
필요할 때 남기는 날것의 기록 공간

0개의 댓글