Next.js project Nextagram

Ng6

lshjju 2025. 9. 28. 15:32

데이터 세팅 합니다.


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>
  );
}

 

 

 

 

 

 

 

'Next.js project Nextagram' 카테고리의 다른 글

Ng7  (0) 2025.09.28
Ng5  (0) 2025.09.28
Ng4  (0) 2025.09.28
Ng3  (0) 2025.09.27
Ng2  (0) 2025.09.27