
2025.06.15
오늘한 내용 : 게시판 기본 페이지 구성 완료 (목록, 상세, 작성, 로그인/회원가입)
WEEK 14 : 실력 다지기 - 프론트엔드
App.jsx
├── Header (공통 상단바)
├── Routes
│ ├── "/" → BoardList.jsx (게시글 목록)
│ ├── "/post/:id" → PostDetail.jsx (게시글 상세 + 댓글)
│ ├── "/new" → CreatePost.jsx (글 작성)
│ ├── "/login" → Login.jsx (로그인)
│ └── "/signup" → Signup.jsx (회원가입)
const [posts, setPosts] = useState([
{
id: 1,
title: "첫 글",
author: "홍길동",
date: "2025-06-15",
content: "내용입니다.",
comments: [
{ id: 1, author: "댓글러", content: "좋은 글입니다!" },
{ id: 2, author: "또다른이", content: "감사합니다." }
]
},
...
]);
comments){posts.map((post) => (
<PostCard key={post.id} post={post} />
))}
post 객체를 받아서 제목, 작성자, 댓글 수 등을 표시/post/:id)로 이동map() 으로 posts 배열을 반복하며 PostCard 렌더링key={post.id} 는 필수: 성능 최적화 + 고유 식별자 역할post는 객체 형태로 전달 → post.title, post.author 등으로 접근{/* 제목: 클릭 시 해당 게시글 상세페이지로 이동 */}
<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})hover:bg-gray-50 transition 같은 Tailwind 사용<div>에 배치useParams() 사용useState(post.comments || [])로 초기화CommentBox는 단순한 입력폼 컴포넌트, 실제 상태는 부모(PostDetail)가 관리함useState는 꼭 import { useState } from "react" 필요e.preventDefault() 는 form의 새로고침을 방지comment.id) 꼭 부여commentList.length와 post.comments.length 혼동하지 말 것 (항상 최신값은 commentList 기준)CommentBox 컴포넌트로 분리<CommentBox onSubmit={handleAddComment} />
commentList state로 관리됨commentAuthor, commentContent)onSubmit 함수는 props로 받아서 부모 컴포넌트에서 댓글 실제 등록 수행CommentBox 자체는 렌더링만 한다. 등록 로직은 부모에서 처리onSubmit 인자로 전달됨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를 업데이트함setPosts() 호출navigate("/") 로 목록으로 이동id: posts.length + 1 로 고유 id 임시 생성 (실제 API 연동 시에는 서버가 생성)author는 입력 없이 자동으로 처리됨handleLogin 함수 내에서 alert → 나중에 API 요청으로 대체<input type="password" /> 로 가려주기| 기능 | 설명 |
|---|---|
| 로그인 입력폼 | id, pw 입력 |
alert 사용 | 테스트용 → 서버 연동 시 API 요청으로 변경 |
handleSignup에서 비밀번호 불일치 시 alert() 처리 후 중단password !== confirmPassword 체크 필수navigate("/login") 으로 이동 처리 필요| 기능 | 설명 |
|---|---|
| 비밀번호 확인 | pw !== confirm으로 일치 여부 검사 |
| 회원가입 요청 | 추후 API로 연결 예정, 현재는 alert() 테스트용 |
| 페이지 | 기능 요약 | 헷갈릴 수 있는 부분 |
|---|---|---|
| BoardList | 게시글 목록 표시 | map 사용 시 key 필수 |
| PostCard | 카드형 게시글 UI | Link 사용, hover 처리 |
| PostDetail | 게시글 상세 + 댓글 | useParams, 댓글 상태 분리 |
| CommentBox | 댓글 입력 전용 | 등록은 부모가 수행 |
| CreatePost | 게시글 등록 | setPosts 직접 호출, navigate 사용, id 생성 주의 |
| Login | 로그인 폼 | 비밀번호 타입, 추후 토큰 처리 |
| Signup | 회원가입 폼 | 비밀번호 확인 필수 |
프론트엔드 틀을 다 만들었다!