반응형
각각 App Router를 직접 구현해보기
SSR 서버에서 데이터 fetch 해서 렌더링하기
SSG 빌드 시 데이터를 fetch 하여 정적 페이지 만들기
CSR 클라이언트 측에서 데이터 fetch 해서 렌더링하기
ISR 정적으로 생성된 페이지를 일정 시간마다 재생성하도록 설정하기
- src 안에 app 폴더만들고 각각 하위폴더 만들기 (SSR,SSG,CSR,ISR)
- 메인 rootpage 를 만들고 각각 nav 를 만들어서 Link 로 연결하기
- RootPage (메인)
- 주의사항 : Link 를 react-router-dom 이 아닌 next/link 로 import 해야 함.
import Link from "next/link";
import React from "react";
const RootPage = () => {
return (
<ul>
<li>
<Link href={"/ssr"}>SSR</Link>
</li>
<li>
<Link href={"/ssg"}>SSG</Link>
</li>
<li>
<Link href={"/csr"}>CSR</Link>
</li>
<li>
<Link href={"/isr"}>ISR</Link>
</li>
</ul>
);
};
export default RootPage;
- SSR Page (서버에서 데이터를 fetch 하여 렌더링하기)
- no-store 로 최신 데이터를 매번 가져와야 할 때 유용하지만 각 요청마다 서버에서 동적으로 페이지를 생성해서 응답 시간이 길어질 수 있다.
- 뉴스피드나 주식 등에 적합하다.
const SSRPage = async () => {
const res = await fetch("http://localhost:5000/posts", {
cache: "no-store",
});
const data = await res.json();
return (
<div>
SSR Page
<div>{JSON.stringify(data)}</div>
</div>
);
};
export default SSRPage;
- SSG (데이터를 fetch하여 정적 페이지를 생성)
- 엄청 빠른 응답 시간을 제공하고, 페이지가 미리 생성되어 있기 때문에 서버 요청 없이 빠르게 사용자에게 전달된다.
- 변경이 적은 블로그나 문서 등에 적합하다.
import React from "react";
import { Post } from "../../../types/route.type";
const SSGPage = async () => {
const res = await fetch("http://localhost:5000/posts");
const posts: Post[] = await res.json();
return (
<div>
<h1>SSG Page</h1>
{posts.map(({ id, title, author }) => (
<div key={id}>
<li>{id}</li>
<li>{title}</li>
<li>{author}</li>
</div>
))}
</div>
);
};
export default SSGPage;
- CSR (클라이언트 측에서 데이터를 fetch하여 페이지에 렌더링)
- use Client 를 사용하여 서버 컴포넌트와 구별하고, 클라이언트에서만 사용할 수 있는 훅들을 사용하기 위해 필요하다.
- useState 는 데이터를 저장하고 관리하는 데 사용
- useEffect 는 컴포넌트가 마운트될 때 특정 작업(여기서는 데이터 가져오기)을 실행하는 훅
- CSR에서는 클라이언트 측에서 페이지가 로드된 후 데이터를 가져와야 하기 때문에 useEffect를 사용하여 비동기 데이터 요청한다.
"use client";
import React, { useEffect, useState } from "react";
import { Post } from "../../../types/route.type";
const CSRPage = () => {
const [posts, setPosts] = useState<Post[]>([]); // posts 상태 정의
const [loading, setLoading] = useState(true); // 데이터 로딩 상태 정의
useEffect(() => {
const fecthPosts = async () => {
try {
const res = await fetch("http://localhost:5000/posts");
const data: Post[] = await res.json();
setPosts(data); // 상태 업데이트
} catch (error) {
console.error("Error fetching posts:", error);
} finally {
setLoading(false); // 로딩 상태 업데이트
}
};
fecthPosts();
}, []);
if (loading) return <div>Loading...</div>;
return (
<div>
<h1>CSR Page</h1>
{posts.map(({ id, title, author }) => (
<div key={id}>
<li>{id}</li>
<li>{title}</li>
<li>{author}</li>
</div>
))}
</div>
);
};
export default CSRPage;
- ISR (정적으로 생성된 페이지를 일정 시간마다 재생성하도록 설정)
- revalidate 를 사용하여 10초마다 페이지를 재생성하지만, 새로고침이 되진 않는다.
import React from "react";
import { Post } from "../../../types/route.type";
export const revalidate = 10;
const ISRPage = async () => {
const res = await fetch("http://localhost:5000/posts");
const posts: Post[] = await res.json();
return (
<div>
<h1>ISR Page</h1>
{posts.map(({ id, title, author }) => (
<div key={id}>
<li>{id}</li>
<li>{title}</li>
<li>{author}</li>
</div>
))}
</div>
);
};
export default ISRPage;
쉽기도 하고 어렵기도 한데 next.js 는 좀 좋은 듯
반응형
'코딩 > Next.js' 카테고리의 다른 글
주특기 플러스주차 과제 끝 (0) | 2024.10.02 |
---|---|
Next.js 주특기 플러스주차 과제 시작 (0) | 2024.10.01 |
Route Handler & Server Action (0) | 2024.09.27 |
Suspense, Loading UI, Streaming SSR/Error UI, Error Handling (3) | 2024.09.27 |
Server Components & Client Component (2) | 2024.09.26 |