728x90
반응형
목차
클라이언트 측에서 데이터를 가져와 쓰게 되면 아래와 같이 페이지 소스에서 보이지 않는다.
따라서 서버 컴포넌트를 이용해야 한다.
use client를 이용한 이전 코드
"use client";
import NewsList from "@/components/news-list";
import { useEffect, useState } from "react";
export default function NewsPage() {
const [news, setNews] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState();
useEffect(() => {
async function fetchNews() {
setIsLoading(true);
const response = await fetch("http://localhost:8080/news");
if (!response.ok) {
setError("Failed to fetch News..");
setIsLoading(false);
}
const news = await response.json();
setIsLoading(false);
setNews(news);
}
fetchNews();
}, []);
if (isLoading) {
return <p>Loading...</p>;
}
if (error) {
return <p>{error}</p>;
}
return (
<>
<h1>News Page</h1>
<NewsList news={news} />
</>
);
}
use server를 이용한 코드
import NewsList from "@/components/news-list";
export default async function NewsPage() {
const response = await fetch("http://localhost:8080/news");
if (!response.ok) {
throw new Error("Failed to fetch news.");
}
const news = await response.json();
return (
<>
<h1>News Page</h1>
<NewsList news={news} />
</>
);
}
아래와 같이 리소스가 담겨 있는 것을 볼 수 있고 이것은 seo에 이점을 줄 수 있다.
로딩 페이지 세밀하게 조정하기
아래와 같이 원하는 컴포넌트에 suspend로 감싸면 그 부분에서 데이터를 가져올 때 loading fallback을 만들 수 있다.
import NewsList from "@/components/news-list";
import {
getAvailableNewsMonths,
getNewsForYear,
getNewsForYearAndMonth,
} from "@/lib/news";
import Link from "next/link";
import { getAvailableNewsYears } from "@/lib/news";
import { Suspense } from "react";
async function FilterHeader({ year, month }) {
const availableYears = await getAvailableNewsYears();
let links = availableYears;
if (
(year && !availableYears.includes(year)) ||
(month && !getAvailableNewsMonths(year).includes(month))
) {
throw new Error("Invalid filter.");
}
if (!month && year) {
links = getAvailableNewsMonths(year);
}
if (year && month) {
links = [];
}
return (
<header id="archive-header">
<nav>
<ul>
{links.map((link) => {
const href = year
? `/archive/${year}/${link}`
: `/archive/${link}`;
return (
<li key={link}>
<Link href={href}>{link}</Link>
</li>
);
})}
</ul>
</nav>
</header>
);
}
async function FilteredNews({ year, month }) {
let news;
if (year && !month) {
news = await getNewsForYear(year);
} else if (year && month) {
news = await getNewsForYearAndMonth(year, month);
}
let newsContent = <p>No news found for the selected period.</p>;
if (news && news.length > 0) {
newsContent = <NewsList news={news} />;
}
return newsContent;
}
export default async function FilteredNewsPage({ params }) {
const filter = (await params).filter;
const selectedYear = filter?.[0];
const selectedMonth = filter?.[1];
const availableYears = await getAvailableNewsYears();
let links = availableYears;
if (!selectedMonth && selectedYear) {
links = getAvailableNewsMonths(selectedYear);
}
if (selectedYear && selectedMonth) {
links = [];
}
return (
<>
<Suspense fallback={<p>Loading filter...</p>}>
<FilterHeader year={selectedYear} month={selectedMonth} />
</Suspense>
<Suspense fallback={<p>Loading news...</p>}>
<FilteredNews year={selectedYear} month={selectedMonth} />
</Suspense>
</>
);
}
//archive 이후 모든 경로 세그먼트에 대해
//활성화되도록 보장
반응형
'코딩 정보 > NextJs' 카테고리의 다른 글
[NextJs] 이미지 최적화에 대해 알아보자 (0) | 2025.04.16 |
---|---|
[NextJs] 캐싱에 대해 더 자세히 알아보자 (0) | 2025.04.15 |
[NextJs] 서버 액션과 관련하여 더 자세히 알아보자 (1) | 2025.04.13 |
[NextJs] 라우터 기능에 대해 빠르게 알아보자 (0) | 2025.04.03 |
[NextJs] 핵심 기능 정리 (1) | 2025.03.12 |