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>
);
}
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,
},
};
}
언제 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(서버 렌더링 오류 페이지)는 사용자가 커스터 마이징 할 수 있다.
개발 중에는 이 파일이 사용되지 않고 대신 개발 오버레이가 표시된다.
'부트캠프 개발일지 2023-2024 > Next.js 넥스트' 카테고리의 다른 글
[12주차] Next.js : Dynamic Routes (0) | 2023.12.22 |
---|---|
[12주차] Next.js : Styled JSX, Custom App (0) | 2023.12.20 |
[12주차] Next.js : Routing, useRouter (0) | 2023.12.20 |
[12주차] Next.js : Static Pre Rendering, Client-side Render, Server-side Render, Hydration (1) | 2023.12.20 |
[12주차] Next.js : Pages Router 라우터 설정하기 (0) | 2023.12.20 |