데이터 세팅 합니다.
import axios from 'axios';
import { useEffect, useState } from 'react';
import React from 'react';
import { usePosts } from './context/PostContext';
page.tsx
json 데이터 사용에 필요한 도구를 임포트 합니다.
import axios from 'axios'; // HTTP 요청을 위한 라이브러리를 가져옵니다.
import { useEffect, useState } from 'react'; // React 훅을 가져옵니다.
import React from 'react'; // React 라이브러리를 가져옵니다.
import { usePosts } from './context/PostContext'; // 게시물 데이터를 제공하는 커스텀 훅을 가져옵니다.
interface Post {
id: number;
title: string;
summary: string;
date: string;
likeIt: string;
}
임포트 아래에 데이터 타입을 세팅 합니다.
// 게시물 데이터의 구조를 정의하는 인터페이스입니다.
interface Post {
id: number; // 게시물 고유 식별자
title: string; // 게시물 제목
summary: string; // 게시물 요약
date: string; // 게시물 날짜
likeIt: string; // 좋아요 수
}
interface PostProps {
posts: Post[];
loading: boolean;
error: string | null;
}
인터페이스 포스트 아래에 컴포넌트 타입을 세팅 합니다.
// Post 컴포넌트의 속성 타입을 정의하는 인터페이스입니다.
interface PostProps {
posts: Post[]; // 게시물 배열
loading: boolean; // 로딩 상태
error: string | null; // 오류 메시지
}
펑션홈 데이터 세팅 합니다.
const { posts, loading, error } = usePosts();
펑션 홈 내부 리턴 위에 여기서 사용 할 데이터를 유즈포스트로 세팅 합니다.
const { posts, loading, error } = usePosts(); // PostContext에서 게시물 데이터를 가져옵니다.
<Post posts={posts} loading={loading} error={error} />
펑션홈 리턴 내부 포스트컴포넌트에 포스트에 전송 할 데이터를 장착합니다.
이 아이들은 프롭스로 전송해야 합니다.
왜냐하면 콘텍스트에이파아이는 유즈포스트스만 사용하고 있기 때문입니다.
<Post posts={posts} loading={loading} error={error} />
{/* 게시물 목록 컴포넌트를 렌더링합니다. */}
펑션포스트 데이터 세팅하고 바인딩 합니다.
function Post({ posts, loading, error }: PostProps)
데이터를 프롭스로 받습니다.
function Post({ posts, loading, error }: PostProps) {
return (
// 이 공간을 죽일듯이 노려 봅니다.
);
}
정확한 지점을 찾아서 아래 코드를 잘라 둡니다.
<div className="">
<div className="card m-3">
<img
src={`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/1.PNG`}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">elegance</h5>
<p className="card-text">
It is a long established fact that a reader will be distracted
</p>
<p className="card-text">
<small>20250228</small>
</p>
<p className="card-text">Like it 25</p>
<Link href="/detail" className="btn btn-outline-secondary">
Detail
</Link>
</div>
</div>
</div>
아마 이코드가 클립보드에 저장되었을 것입니다.
function Post({ posts, loading, error }: PostProps) {
return (
<>
{loading && <p>로딩 중...</p>}
{error && <p className="text-danger">{error}</p>}
{!loading && !error && (
<div>
omission...
</div>
)}
</>
);
}
주석처리된 곳에 위 코드를 코딩합니다.
구라태그로 말아주고 에러처리 합니다.
function Post({ posts, loading, error }: PostProps) {
return (
<>
{loading && <p>로딩 중...</p>} {/* 데이터 로딩 중일 때 표시됩니다. */}
{error && <p className="text-danger">{error}</p>} {/* 오류가 발생했을 때 표시됩니다. */}
{!loading && !error && ( // 로딩 중이 아니고 오류가 없을 때 게시물을 표시합니다.
<div>
omission...
</div>
)}
</>
);
}
function Post({ posts, loading, error }: PostProps) {
return (
<>
{loading && <p>로딩 중...</p>}
{error && <p className="text-danger">{error}</p>}
{!loading && !error && (
<div className="">
<div className="card m-3">
<img
src={`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/1.PNG`}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">elegance</h5>
<p className="card-text">
It is a long established fact that a reader will be distracted
</p>
<p className="card-text">
<small>20250228</small>
</p>
<p className="card-text">Like it 25</p>
<Link href="/detail" className="btn btn-outline-secondary">
Detail
</Link>
</div>
</div>
</div>
)}
</>
);
}
잘라두었던 코드 페이스트 합니다.
function Post({ posts, loading, error }: PostProps) {
return (
<>
{loading && <p>로딩 중...</p>}
{error && <p className="text-danger">{error}</p>}
{!loading && !error && (
<div>
{posts.map((post) => (
<div key={post.id} className="card m-3">
<img
src={
`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/` +
(post.id + 1) +
`.PNG`
}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">{post.title}</h5>
<p className="card-text">{post.summary}</p>
<p className="card-text">
<small>{post.date}</small>
</p>
<p className="card-text">Like it {post.likeIt}</p>
<Link
href={`/posts/${post.id}`}
className="btn btn-outline-secondary"
>
Detail
</Link>
</div>
</div>
))}
</div>
)}
</>
);
}
데이터바인딩 합니다.
맨위 디브 className="" 는 삭제 합니다.
<div>
{posts.map((post) => ( // 각 게시물에 대해 카드 형태로 표시합니다.
<div key={post.id} className="card m-3">
<img
src={
`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/` +
(post.id + 1) +
`.PNG`
} // 게시물에 해당하는 이미지를 가져옵니다.
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">{post.title}</h5> {/* 게시물 제목을 표시합니다. */}
<p className="card-text">{post.summary}</p> {/* 게시물 요약을 표시합니다. */}
<p className="card-text">
<small>{post.date}</small> {/* 게시물 날짜를 표시합니다. */}
</p>
<p className="card-text">Like it {post.likeIt}</p> {/* 좋아요 수를 표시합니다. */}
<Link
href={`/posts/${post.id}`} // 게시물 상세 페이지로 이동하는 링크입니다.
className="btn btn-outline-secondary"
>
Detail
</Link>
</div>
</div>
))}
</div>
test

데이터바인딩 체크 합니다.
디테일 링크는 아직 준비되지 않았습니다.
다음장에서 처리 합니다.
Completion
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
import Link from 'next/link';
import dataTexts from './data/dataText';
import axios from 'axios';
import { useEffect, useState } from 'react';
import React from 'react';
import { usePosts } from './context/PostContext';
interface Post {
id: number;
title: string;
summary: string;
date: string;
likeIt: string;
}
interface PostProps {
posts: Post[];
loading: boolean;
error: string | null;
}
interface DataText {
main: string;
subCaps1: string;
sub1: string;
subCaps2: string;
sub2: string;
subCaps3: string;
sub3: string;
footer: string;
}
export default function Home() {
const { posts, loading, error } = usePosts();
return (
<main>
<h4>{dataTexts[0].main}</h4>
<Post posts={posts} loading={loading} error={error} />
<Pagination />
</main>
);
}
function Post({ posts, loading, error }: PostProps) {
return (
<>
{loading && <p>로딩 중...</p>}
{error && <p className="text-danger">{error}</p>}
{!loading && !error && (
<div className="">
{posts.map((post) => (
<div key={post.id} className="card m-3">
<img
src={
`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/` +
(post.id + 1) +
`.PNG`
}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">{post.title}</h5>
<p className="card-text">{post.summary}</p>
<p className="card-text">
<small>{post.date}</small>
</p>
<p className="card-text">Like it {post.likeIt}</p>
<Link
href={`/posts/${post.id}`}
className="btn btn-outline-secondary"
>
Detail
</Link>
</div>
</div>
))}
</div>
)}
</>
);
}
function Pagination() {
return (
<nav aria-label="Page navigation example">
<ul className="pagination justify-content-center">
<li className="page-item disabled">
<a className="page-link">Previous</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
1
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
2
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
3
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
Next
</a>
</li>
</ul>
</nav>
);
}
Comment ver
'use client'; // Next.js에서 클라이언트 컴포넌트임을 나타내는 지시어입니다.
import 'bootstrap/dist/css/bootstrap.min.css'; // 부트스트랩 CSS를 가져옵니다.
import 'bootstrap/dist/js/bootstrap.bundle.min.js'; // 부트스트랩 JavaScript를 가져옵니다.
import Link from 'next/link'; // Next.js의 페이지 간 이동을 위한 컴포넌트를 가져옵니다.
import dataTexts from './data/dataText'; // 텍스트 데이터를 가져옵니다.
import axios from 'axios'; // HTTP 요청을 위한 라이브러리를 가져옵니다.
import { useEffect, useState } from 'react'; // React 훅을 가져옵니다.
import React from 'react'; // React 라이브러리를 가져옵니다.
import { usePosts } from './context/PostContext'; // 게시물 데이터를 제공하는 커스텀 훅을 가져옵니다.
// 게시물 데이터의 구조를 정의하는 인터페이스입니다.
interface Post {
id: number; // 게시물 고유 식별자
title: string; // 게시물 제목
summary: string; // 게시물 요약
date: string; // 게시물 날짜
likeIt: string; // 좋아요 수
}
// Post 컴포넌트의 속성 타입을 정의하는 인터페이스입니다.
interface PostProps {
posts: Post[]; // 게시물 배열
loading: boolean; // 로딩 상태
error: string | null; // 오류 메시지
}
// 텍스트 데이터의 구조를 정의하는 인터페이스입니다.
interface DataText {
main: string; // 메인 텍스트
subCaps1: string; // 첫 번째 소제목 (대문자)
sub1: string; // 첫 번째 소제목 내용
subCaps2: string; // 두 번째 소제목 (대문자)
sub2: string; // 두 번째 소제목 내용
subCaps3: string; // 세 번째 소제목 (대문자)
sub3: string; // 세 번째 소제목 내용
footer: string; // 푸터 텍스트
}
// 메인 홈 페이지 컴포넌트입니다.
export default function Home() {
const { posts, loading, error } = usePosts(); // PostContext에서 게시물 데이터를 가져옵니다.
return (
<main>
<h4>{dataTexts[0].main}</h4> {/* dataTexts 배열의 첫 번째 항목에서 main 텍스트를 표시합니다. */}
<Post posts={posts} loading={loading} error={error} /> {/* 게시물 목록 컴포넌트를 렌더링합니다. */}
<Pagination /> {/* 페이지네이션 컴포넌트를 렌더링합니다. */}
</main>
);
}
// 게시물 목록을 표시하는 컴포넌트입니다.
function Post({ posts, loading, error }: PostProps) {
return (
<>
{loading && <p>로딩 중...</p>} {/* 데이터 로딩 중일 때 표시됩니다. */}
{error && <p className="text-danger">{error}</p>} {/* 오류가 발생했을 때 표시됩니다. */}
{!loading && !error && ( // 로딩 중이 아니고 오류가 없을 때 게시물을 표시합니다.
<div className="">
{posts.map((post) => ( // 각 게시물에 대해 카드 형태로 표시합니다.
<div key={post.id} className="card m-3">
<img
src={
`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/` +
(post.id + 1) +
`.PNG`
} // 게시물에 해당하는 이미지를 가져옵니다.
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">{post.title}</h5> {/* 게시물 제목을 표시합니다. */}
<p className="card-text">{post.summary}</p> {/* 게시물 요약을 표시합니다. */}
<p className="card-text">
<small>{post.date}</small> {/* 게시물 날짜를 표시합니다. */}
</p>
<p className="card-text">Like it {post.likeIt}</p> {/* 좋아요 수를 표시합니다. */}
<Link
href={`/posts/${post.id}`} // 게시물 상세 페이지로 이동하는 링크입니다.
className="btn btn-outline-secondary"
>
Detail
</Link>
</div>
</div>
))}
</div>
)}
</>
);
}
// 페이지네이션을 표시하는 컴포넌트입니다.
function Pagination() {
return (
<nav aria-label="Page navigation example">
<ul className="pagination justify-content-center"> {/* 중앙 정렬된 페이지네이션 컴포넌트입니다. */}
<li className="page-item disabled">
<a className="page-link">Previous</a> {/* 이전 페이지 버튼 (현재 비활성화됨) */}
</li>
<li className="page-item">
<a className="page-link" href="#">
1 {/* 페이지 1 링크 */}
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
2 {/* 페이지 2 링크 */}
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
3 {/* 페이지 3 링크 */}
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
Next {/* 다음 페이지 버튼 */}
</a>
</li>
</ul>
</nav>
);
}
