Skip to content

feat: 7주차 첫번째, 두번째 미션#68

Open
kimdoyeon1234 wants to merge 15 commits into
dorifrom
week7/Dori-m2
Open

feat: 7주차 첫번째, 두번째 미션#68
kimdoyeon1234 wants to merge 15 commits into
dorifrom
week7/Dori-m2

Conversation

@kimdoyeon1234
Copy link
Copy Markdown
Collaborator

@kimdoyeon1234 kimdoyeon1234 commented May 15, 2026

📌 작업 내용

  • 어떤 작업을 했는지 한 줄 요약

  • 마이페이지 유저 정보 관리 및 활동 내역(좋아요/작성글) 조회 기능을 구현했습니다.

  • LP 상세 페이지의 핵심 상호작용(좋아요 낙관적 업데이트, 댓글 무한 스크롤)을 구축했습니다.

  • LP 리스트의 정렬 신규 LP 등록 기능을 구현했습니다.

✨ 상세 작업 내용

  1. 마이페이지 (MyPage)
    탭 시스템: '내가 좋아요 한 LP'와 '내가 작성한 LP'를 분리하여 조회할 수 있는 탭 UI 구현.
    프로필 관리: 닉네임 수정 시 낙관적 업데이트(Optimistic Update)를 적용하여 사용자에게 즉각적인 피드백 제공.
    무한 스크롤: react-intersection-observer와 useInfiniteQuery를 결합하여 활동 내역 페이징 처리.

  2. LP 상세 및 상호작용 (LpDetailPage)
    좋아요 시스템:좋아요 클릭 시 즉시 UI 반영(낙관적 업데이트).
    중복 요청 시 발생하는 409 Conflict 에러 예외 처리 로직을 통해 서버 데이터와 UI 상태 동기화 유지.
    댓글 시스템: 댓글 작성 기능 및 무한 스크롤을 통한 댓글 목록 조회.
    시각적 요소: 레코드판 회전 애니메이션 및 글래스모피즘(Glassmorphism) 디자인 적용.

  3. LP 리스트 및 생성 (LpListPage)
    데이터 정렬: 최신순/오래된순 필터링 기능 제공.
    태그 시스템: 실시간 태그 추가 및 삭제 기능이 포함된 등록 모달 구현.

📸 스크린샷

녹음 2026-05-18 211225

✅ 체크리스트

  • 기능 정상 작동 확인
  • 불필요한 주석 삭제
  • 해당 주차 키워드 내용 이해

@kimdoyeon1234 kimdoyeon1234 changed the title feat: 7주차 두번째 미션 feat: 7주차 첫번째, 두번째 미션 May 15, 2026
@kimdoyeon1234 kimdoyeon1234 self-assigned this May 18, 2026
Copy link
Copy Markdown
Collaborator

@yewon20804 yewon20804 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 하는 쪽이 더 자연스러운 흐름인 것 같습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants