[TIL/크래프톤 정글] DAY 98

배재준·2025년 6월 15일

크래프톤 정글 - TIL

목록 보기
90/93
post-thumbnail

2025.06.15

TIL(TODAY I LEARN)


  • 오늘한 내용 : 게시판 기본 페이지 구성 완료 (목록, 상세, 작성, 로그인/회원가입)

  • WEEK 14 : 실력 다지기 - 프론트엔드


구현

프론트엔드 게시판 구현 정리

전체 구조

App.jsx
├── Header (공통 상단바)
├── Routes
│   ├── "/"          → BoardList.jsx  (게시글 목록)
│   ├── "/post/:id"  → PostDetail.jsx (게시글 상세 + 댓글)
│   ├── "/new"       → CreatePost.jsx (글 작성)
│   ├── "/login"     → Login.jsx      (로그인)
│   └── "/signup"    → Signup.jsx     (회원가입)

1) 게시글 구조 (App.jsx)

const [posts, setPosts] = useState([
  {
    id: 1,
    title: "첫 글",
    author: "홍길동",
    date: "2025-06-15",
    content: "내용입니다.",
    comments: [
      { id: 1, author: "댓글러", content: "좋은 글입니다!" },
      { id: 2, author: "또다른이", content: "감사합니다." }
    ]
  },
  ...
]);
  • 게시글 데이터는 state로 관리
  • 댓글은 게시글 객체 안의 배열로 포함 (comments)

2) 게시글 목록 렌더링 (BoardList.jsx)

{posts.map((post) => (
  <PostCard key={post.id} post={post} />
))}
  • PostCard 컴포넌트 역할
    • 개별 게시글을 카드 형태로 보여주는 UI
    • props로 post 객체를 받아서 제목, 작성자, 댓글 수 등을 표시
    • 클릭 시 해당 게시글 상세 페이지(/post/:id)로 이동
  • 주요 개념
    • map() 으로 posts 배열을 반복하며 PostCard 렌더링
    • key={post.id} 는 필수: 성능 최적화 + 고유 식별자 역할
  • 헷갈릴 수 있는 부분
    • props로 넘긴 post는 객체 형태로 전달 → post.title, post.author 등으로 접근

3) 게시글 카드 (PostCard.jsx)

{/* 제목: 클릭 시 해당 게시글 상세페이지로 이동 */}
      <Link to={`/post/${post.id}`}>
        <h2 className="text-xl font-semibold text-black-600 hover:underline">
          {post.title}
        </h2>
      </Link>
      
{/* 본문 미리보기 */}
      <p className="text-gray-600 mt-2">
        {post.content.length > 30
          ? post.content.slice(0, 30) + "..."
          : post.content}
      </p>
  • 주요 개념
    • Link 컴포넌트를 통해 상세 페이지로 이동 (to=/post/${post.id})
    • 본문 길이가 길때 30자 제한을 두고 … 으로 표시
  • 주의 사항
    • 카드 전체에 hover 효과 주고 싶으면 div에 hover:bg-gray-50 transition 같은 Tailwind 사용
    • 날짜, 작성자, 댓글 수 등의 메타정보는 분리해서 <div>에 배치

4) 게시글 상세 보기 (PostDetail.jsx)

  • 주요 개념
    • URL에서 post ID 추출: useParams() 사용
    • 댓글 상태는 로컬에서 useState(post.comments || [])로 초기화
    • CommentBox는 단순한 입력폼 컴포넌트, 실제 상태는 부모(PostDetail)가 관리함
  • 주의 사항
    • useState는 꼭 import { useState } from "react" 필요
    • e.preventDefault() 는 form의 새로고침을 방지
    • 댓글 목록을 map할 때 key값 (comment.id) 꼭 부여
    • commentList.lengthpost.comments.length 혼동하지 말 것 (항상 최신값은 commentList 기준)

댓글 등록 방식

  • 댓글 입력은 CommentBox 컴포넌트로 분리
  • 댓글 등록은 상위에서 관리:
<CommentBox onSubmit={handleAddComment} />
  • 댓글 목록은 commentList state로 관리됨

5) 댓글 입력 컴포넌트 (CommentBox.jsx)

  • 주요 개념
    • 상태는 내부에서 관리 (commentAuthor, commentContent)
    • onSubmit 함수는 props로 받아서 부모 컴포넌트에서 댓글 실제 등록 수행
  • 주의 사항
    • CommentBox 자체는 렌더링만 한다. 등록 로직은 부모에서 처리
    • form 태그 안에서 submit 발생 → 입력값이 onSubmit 인자로 전달됨

5) 글 작성 페이지 (CreatePost.jsx)

import { useState } from "react";
import { useNavigate } from "react-router-dom";

function CreatePost({ posts, setPosts }) {
  const [title, setTitle] = useState("");
  const [author, setAuthor] = useState("");
  const [content, setContent] = useState("");
  const navigate = useNavigate();

  const handleSubmit = (e) => {
    e.preventDefault();

    const newPost = {
      id: posts.length + 1, // 실제 서비스에서는 uuid 또는 DB id 사용
      title,
      author,
      date: new Date().toISOString().split("T")[0], // 오늘 날짜 yyyy-mm-dd
      comments: 0,
      content,
    };

    setPosts([...posts, newPost]); // 새 글 추가
    navigate("/"); // 목록으로 이동
  };
...
}
  • 주요 개념
    • 제목, 작성자, 내용 입력값은 useState로 관리
    • 작성 완료 시 App.jsx에서 setPosts()로 직접 posts를 업데이트함
      → props로 받은 setPosts() 호출
    • navigate("/") 로 목록으로 이동
  • 주의 사항
    • id: posts.length + 1 로 고유 id 임시 생성 (실제 API 연동 시에는 서버가 생성)
    • 로그인 기능과 연결되면 author는 입력 없이 자동으로 처리됨

6) 로그인 페이지 (Login.jsx)

  • 주요 개념
    • 로그인 정보는 id, pw 두 개의 state로 관리
    • handleLogin 함수 내에서 alert → 나중에 API 요청으로 대체
  • 주의 사항
    • 비밀번호는 <input type="password" /> 로 가려주기
    • 실제 로그인 처리 성공 시 토큰 저장 필요 (ex. localStorage)
기능설명
로그인 입력폼id, pw 입력
alert 사용테스트용 → 서버 연동 시 API 요청으로 변경

7) 회원가입 페이지 (Signup.jsx)

  • 주요 개념
    • 비밀번호, 비밀번호 확인 값 두 개 필요 → 일치 여부 확인
    • handleSignup에서 비밀번호 불일치 시 alert() 처리 후 중단
  • 주의 사항
    • password !== confirmPassword 체크 필수
    • 중복 가입, 유효성 검사 등은 추후 백엔드 연동 시 구현
    • 회원가입 성공 시 navigate("/login") 으로 이동 처리 필요
기능설명
비밀번호 확인pw !== confirm으로 일치 여부 검사
회원가입 요청추후 API로 연결 예정, 현재는 alert() 테스트용

~ 전체 정리 요약 ~

페이지기능 요약헷갈릴 수 있는 부분
BoardList게시글 목록 표시map 사용 시 key 필수
PostCard카드형 게시글 UILink 사용, hover 처리
PostDetail게시글 상세 + 댓글useParams, 댓글 상태 분리
CommentBox댓글 입력 전용등록은 부모가 수행
CreatePost게시글 등록setPosts 직접 호출, navigate 사용, id 생성 주의
Login로그인 폼비밀번호 타입, 추후 토큰 처리
Signup회원가입 폼비밀번호 확인 필수

프론트엔드 틀을 다 만들었다!

0개의 댓글