본문 바로가기
부트캠프 개발일지 2023-2024/Next.js 넥스트

[12주차] Next.js : client-side render VS server-side render

by whereanna00 2023. 12. 21.

client-side render

말 그대로, react.js 즉 client-side에서 render를 하는 것.

보통 api get 요청을 할 때(데이터를 가져올 때), useEffect 안에서 axios 또는 fetch로 async~await을 통해 가져온다.

여기서 api key는 next.config.js 에서 rewrites()으로 숨겨줘도 되고, rewrites + .env(환경변수) 설정을 통해 숨겨줄 수도 있다.

 

 

rewrites + .env 버전

더보기
// .env
API_KEY=abcdefg123456789
// next.config.js

/** @type {import('next').NextConfig} */

const API_KEY = process.env.API_KEY;

const nextConfig = {
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
    ];
  },
};

module.exports = nextConfig;
// pages/index.jsx

import Seo from "@/components/Seo";
import { useEffect, useState } from "react";
import axios, { Axios } from "axios";

export default function Home() {
  const [movies, setMovies] = useState([]);
  useEffect(() => {
    const fetchMovies = async () => {
      const response = await axios.get(`/api/movies`);
      setMovies([...response.data.results]);
      console.log("response.data.results", response.data.results);
    };
    fetchMovies();
  }, []);

  return (
    <div>
      <Seo title="Home" />
      {!movies && <h4>Loading...</h4>}
      <div className="movieCardContainer">
        {movies?.map((movie) => {
          return (
            <div className="movieCard" key={movie.id}>
              <img
                src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
              />
              {console.log("imgpath", movie.poster_path)}
              <h4>{movie.title}</h4>
            </div>
          );
        })}
      </div>
    </div>
  );
}

 

 

GitHub - dancinncoder/movie-app-nextjs

Contribute to dancinncoder/movie-app-nextjs development by creating an account on GitHub.

github.com

 

 

server-side render

백엔드 서버에서 api get 요청을 한 후, 데이터가 모두 받아와 지면 client-side (react.js)로 넘겨주는 방식.

getServerSideProps() 함수를 사용하고 이 함수 안에 있는 코드는 모두 서버쪽에서만 작동하게 된다.

더보기
// index.jsx

export async function getServerSideProps() {
  // 여기 안에 있는 코드는 모두 server쪽에서만 작동하게 된다
  const response = await axios.get(`http://localhost:3000/api/movies`);
  const results = response.data.results;
  return {
    props: {
      results,
    },
  };
}

 

백엔드 서버에서 API GET 요청을 한 후 데이터를 가져와서 getServerSideProps 함수를 사용해 클라이언트 측으로 전달하는 방식이다. 이 함수는 서버 측에서 최초 한 번 실행되지만, 그 이후에는 클라이언트 측에서 페이지 전환 시에도 실행된다. 이 함수에서 반환되는 객체는 props 키를 가지고 있으며, 이 데이터는 _app.jsx의 App 컴포넌트의 pageProps로 전달되어 최상위 컴포넌트에서 사용할 수 있다. 이를 통해 서버에서 가져온 데이터를 페이지 간에 공유할 수 있다.

// _app.jsx

import "../styles/globals.css";
import Layout from "@/components/Layout";

export default function App({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
      {/* Layout의 children */}
    </Layout>
  );
}
// index.jsx

import Seo from "@/components/Seo";
import axios, { Axios } from "axios";

export default function Home({ results }) {


  return (
    <div>
      <Seo title="Home" />
      <div className="movieCardContainer">
        {results?.map((movie) => {
          return (
            <div className="movieCard" key={movie.id}>
              <img
                src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
              />
              {console.log("imgpath", movie.poster_path)}
              <h4>{movie.title}</h4>
            </div>
          );
        })}
      </div>
    </div>
  );
}

export async function getServerSideProps() {
  // 여기 안에 있는 코드는 모두 server쪽에서만 작동하게 된다
  const response = await axios.get(`http://localhost:3000/api/movies`);
  const results = response.data.results;
  return {
    props: {
      results,
    },
  };
}

 

 

GitHub - dancinncoder/movie-app-nextjs

Contribute to dancinncoder/movie-app-nextjs development by creating an account on GitHub.

github.com

 

 

언제 getServerSideProps를 사용해야 하나?

request time에 반드시 데이터를 fetch해와야 하는 페이지를 pre-render해야 하는 경우에만 getServerSideProps를 사용해야 한다.
데이터를 pre-render할 필요가 없다면 client side에서 데이터를 가져오는 것을 고려해야 한다.

클라이언트 측에서 데이터 가져오는 과정 (Fetching data on the client side)
페이지에 자주 업데이트되는 데이터가 포함되어 있고 데이터를 pre-render할 필요가 없는 경우 클라이언트 측에서 데이터를 가져올 수 있다.
1. 먼저 데이터가 없는 페이지를 즉시 표시
2. 페이지의 일부는 Static Generation을 사용해 pre-render할 수 있다.
3. 없는 데이터를 위해 loading 상태를 표시할 수 있다.
4. 그런 다음 클라이언트 측에서 데이터를 가져와 준비가 되면 표시한다.

이 접근 방식은 예를 들어 사용자 대시보드 페이지에 적합하다.
왜냐하면 대시보드는 사용자별 비공개 페이지이기 때문에 SEO와는 관련이 없으며 페이지를 미리 렌더링할 필요가 없다. 또한 데이터는 자주 업데이트되므로 요청 시 데이터를 가져와야 한다.

getServerSideProps가 오류 페이지를 렌더링합니까?
getServerSideProps 내부에서 오류가 발생하면 pages/500.js 파일이 표시된다.
500 page(서버 렌더링 오류 페이지)는 사용자가 커스터 마이징 할 수 있다.
개발 중에는 이 파일이 사용되지 않고 대신 개발 오버레이가 표시된다.

 

 

 

Data Fetching: getServerSideProps | Next.js

Fetch data on each request with `getServerSideProps`.

nextjs.org

 

728x90
반응형