feat: 7주차 첫번째, 두번째 미션#68
Open
kimdoyeon1234 wants to merge 15 commits into
Open
Conversation
yewon20804
reviewed
May 19, 2026
Collaborator
yewon20804
left a comment
There was a problem hiding this comment.
7주차 미션 확인했습니다 ! useMutation 사용 및 좋아요 낙관적 업데이트까지 구현해주셨습니다 😀
코멘트 확인 부탁드립니다 ~
1. LpDetailPage.tsx — useEffect 의존성 배열에 fetchNextPage 누락
// ❌ 현재
useEffect(() => { if (inView && hasNextPage) fetchNextPage(); }, [inView, hasNextPage]);
// ✅ 수정
useEffect(() => { if (inView && hasNextPage) fetchNextPage(); }, [inView, hasNextPage, fetchNextPage]);
fetchNextPage가 의존성 배열에 빠져 있어서 ESLint 경고가 발생할 수 있습니다 !
2. LpDetailPage.tsx — 댓글 작성 시 빈 문자열 검증 없음
// ❌ 현재
<button onClick={() => createComment.mutate(commentInput)}>POST</button>
// ✅ 수정
<button
onClick={() => {
if (!commentInput.trim()) return alert('댓글을 입력해주세요!');
createComment.mutate(commentInput.trim());
}}
disabled={createComment.isPending}
>
{createComment.isPending ? 'POSTING...' : 'POST'}
</button>
아무것도 입력하지 않은 채로 POST 버튼을 누를 수 있어서 빈 댓글이 등록될 수 있어 입력값 검증을 추가해주시면 더 좋은 코드가 될 것 같습니다 !
3. LpCard.tsx — any 타입 제거
// ❌ 현재
const LpCard = ({ lp }: { lp: any }) => { ... }
// ✅ 수정 — 타입 정의
interface Lp {
id: number;
title: string;
thumbnail: string;
createdAt: string;
likes?: { id: number }[];
}
const LpCard = ({ lp }: { lp: Lp }) => { ... }
any 대신 interface로 타입을 명확하게 정의해두면 타입 안정성을 생겨 더 좋은 것 같습니다!
4. toggleLike — onSettled의 setTimeout 제거 권장
// ❌ 현재 — 0.5초 딜레이로 동기화
onSettled: () => {
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ['lp', lpIdNum] });
}, 500);
}
// ✅ 수정 — 즉시 동기화 (낙관적 업데이트가 이미 처리했으므로 딜레이 불필요)
onSettled: (data, error) => {
const isConflict = (error as any)?.response?.status === 409;
if (!isConflict) {
queryClient.invalidateQueries({ queryKey: ['lp', lpIdNum] });
queryClient.invalidateQueries({ queryKey: ['myList'] });
}
}
낙관적 업데이트로 UI는 이미 반영된 상태라면 setTimeout으로 딜레이를 두기보다 바로 invalidateQueries 하는 쪽이 더 자연스러운 흐름인 것 같습니다!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 작업 내용
어떤 작업을 했는지 한 줄 요약
마이페이지 유저 정보 관리 및 활동 내역(좋아요/작성글) 조회 기능을 구현했습니다.
LP 상세 페이지의 핵심 상호작용(좋아요 낙관적 업데이트, 댓글 무한 스크롤)을 구축했습니다.
LP 리스트의 정렬 신규 LP 등록 기능을 구현했습니다.
✨ 상세 작업 내용
마이페이지 (MyPage)
탭 시스템: '내가 좋아요 한 LP'와 '내가 작성한 LP'를 분리하여 조회할 수 있는 탭 UI 구현.
프로필 관리: 닉네임 수정 시 낙관적 업데이트(Optimistic Update)를 적용하여 사용자에게 즉각적인 피드백 제공.
무한 스크롤: react-intersection-observer와 useInfiniteQuery를 결합하여 활동 내역 페이징 처리.
LP 상세 및 상호작용 (LpDetailPage)
좋아요 시스템:좋아요 클릭 시 즉시 UI 반영(낙관적 업데이트).
중복 요청 시 발생하는 409 Conflict 에러 예외 처리 로직을 통해 서버 데이터와 UI 상태 동기화 유지.
댓글 시스템: 댓글 작성 기능 및 무한 스크롤을 통한 댓글 목록 조회.
시각적 요소: 레코드판 회전 애니메이션 및 글래스모피즘(Glassmorphism) 디자인 적용.
LP 리스트 및 생성 (LpListPage)
데이터 정렬: 최신순/오래된순 필터링 기능 제공.
태그 시스템: 실시간 태그 추가 및 삭제 기능이 포함된 등록 모달 구현.
📸 스크린샷
✅ 체크리스트