-
Notifications
You must be signed in to change notification settings - Fork 0
[3주차 과제] 숫자 카드 짝 맞추기 #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
jeonghoon11
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR 잘 봤어요! useEffect에 대해 아티클을 작성하셨더라구요! useEffect는 봐도 봐도 너무 어려운것 같아요ㅠㅠㅠㅠ 이번 과제하면서 DOM 구조를 생각하면서 개발하신것 너무 대단합니다!!
저도 이번 과제 자체가 상태관리 할게 너무 많아서 코드 짜는게 너무 어려웠어요ㅠㅠ
고생 많으셨습니다! 4주차 과제도 파이팅!
| <S.EmptyMessage>아직 뒤집은 카드가 없어요</S.EmptyMessage> | ||
| ) : ( | ||
| history.map((item, index) => ( | ||
| <S.HistoryItem key={index} isSuccess={item.isSuccess}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key값을 고유 정보로 대체하면 더 안정적일것 같아요!
예) 레벨 + 시간
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useGame 훅에 10개가 넘는 상태가 존재해요. 따라서 부분적으로 분리해서 관리하면 더 단일 책임 원칙에 적합할것 같네요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Game 페이지에서 여러 useEffect가 서로 의존하며 동작하는 구조라 사이드이펙트가 발생할 가능성이 있어 보여요!
타이머 관리, 매칭 성공 처리, 모달 카운트다운 같은 로직을 커스텀 훅으로 분리하면 책임이 더 명확해지고 유지보수도 쉬워질 것 같아요
seunghye-rain
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전체적으로 훅·유틸·스타일 분리가 잘 되어 있고 타이머에 많은 고민 하신거 잘 보였어요!! 이모션으로 깔끔하게 사용하신 것도 잘 봤습니다!!
3주차 과제 수고하셨어용🥹
| </S.EmptyText> | ||
| ) : ( | ||
| records.map((record, index) => ( | ||
| <S.TableRow key={index}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key 값은 index보다 다른 값을 넣어주는게 좋을 것 같아요!
| const startTimer = useCallback(() => { | ||
| setIsRunning((current) => { | ||
| if (!current) { | ||
| setStartTime(Date.now()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Date.now()를 기반으로 시간 계산한거 좋은 것 같아요..!!
👽 과제 명세
👽 과제 명세
💡 기본 과제
헤더
숫자 카드 짝 맞추기 게임
4 x 4로 고정한다.buildDeck사용 가능)2.1 게임 보드
2.2 게임 진행 상황
랭킹 기능
현재 시각,레벨,클리어 시간이 포함된다. (클리어 시간은 소수점 둘째 자리까지)클리어 시간오름차순이다. (빠른 기록이 위)🔥 심화 과제
게임 레벨 기능
Level 1:
4 x 48쌍 제한 시간 45초Level 2:
4 x 612쌍 제한 시간 60초Level 3:
6 x 618쌍 제한 시간 100초안내 메시지
시각 효과 추가
참고: https://ko.react.dev/reference/react-dom/createPortal
랭킹 정렬 기능
높은 레벨이 위쪽, 같은 레벨에서는 빠른 시간이 위쪽으로 정렬
공유과제
제목: useEffect 더 잘 다루기 (ft. 의존성 배열 & clean up 함수)
링크 첨부 : https://velog.io/@dotsi0/useEffect-%EB%8D%94-%EC%9E%98-%EB%8B%A4%EB%A3%A8%EA%B8%B0-ft.-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%B0%B0%EC%97%B4-clean-up-%ED%95%A8%EC%88%98
🔧 구현 요약 및 새로 배운 점
🛸 폴더 구조
CSS 라이브러리 선택 이유
emotion라이브러리를 사용했어요. 1, 2주차에서 사용한 styled.component와 적용 방식이 비슷해서 익숙한 느낌이었어요! 아래는 시간대별로 CSS 라이브러리의 인기를 확인할 수 있는 npm trend라는 사이트예요!localStorage 관련 부분은 상태 관리할 부분이 따로 없이 save된 상태를 get 또는 clear만 하면 된다고 생각해서 리렌더링을 유발하는 훅 보단 유틸 함수로 구현했어요.
0.01초 단위로 카운트다운하는 타이머를☺️
setInterval과useRef로 구현했어요. 클리어 시간은 현지 시간에서 초기 시간을 빼서 계산했고, stopTimer가 시간을 반환하도록 했어요. 추가로 useCallback을 사용해서 함수 메모이제이션 부분을 적용해서 무한 루프를 방지했어요.사실 3차 세미나 때 잠깐 언급되었던 useRef가 조금은 생소했어요. 대부분의 상태 관리는 useState로만 했었고 둘의 차이를 명백하게는 몰랐는데 이번 기회에 정리할 수 있어 유익했어요
👾 결국 React에서 ref는 DOM을 조작하기 위해 사용하는 건데, 전 아래와 같이 사용했어요.
useRef는
.current프로퍼티로 전달된 인자(intervalRef)로 초기화된 변경 가능한 ref 객체를 반환해요. useRef로 만든 객체를 수정하는 것은 컴포넌트의 렌더링과 무관합니다. 즉,.current프로퍼티를 변형하는 것이 리렌더링을 발생시키지 않는다는 거예요!useState와 useRef는 둘 다 상태를 기억하고 변경을 감지하지만, 그 성격이 완전히 달랐어요. 그 차이를 잘 보여주는게 이번 timer의 예시였다고 생각합니다 😊
의존성 체인이 무한 루프를 유발한다는 걸 배우고, setState는 의존성 배열에서 생략 가능하다는 걸 배웠어요.
1주차 인터스에서 배운 내용을 바탕으로 rotateY와 3D transform으로 카드 뒤집기 애니메이션 부분을 구현했어요 🤩
랭킹에는 localStorage를 활용한 기록 저장 부분을 적용해서 클리어 시 자동으로 기록을 저장해요. 또한 2주차 인터스에서 배운 formatDate로 날짜 포맷팅을 적용했어요! 🤩
🥲 구현 과정에서 어려웠던 & 고민했던 부분
resetTimer → stopTimer → startTime 의존성 체인을 끊지 못해서 타이머 작동이 안되거나, 타이머 내에 클로저 문제로 인해 최종 클리어 타임을 잘못 계산해서 랭킹에 클리어 타임 노출이 안되는 이슈가 있었어요. 비동기 상태 업데이트와 동기 계산을 분리해야 한다는 걸 확실히 배웠어요
명세만 봤을 때는 몰랐는데 생각보다 구현할 파일이 많았어요. 전 프로젝트 전에는 항상 어떤 걸 컴포넌트화해야할지를 먼저 고민하고 시작하는데, 다음부턴 컴포넌트부터 만들지 말고 파일 구조를 먼저 세팅하면서 구조를 그려봐야겠어요!
🔭 리뷰 요청 포인트 & 질문
📷 결과물
레벨 선택
1단계 플레이 & 랭킹
2025-11-11.11.10.17.mov
타임 아웃 모달
2025-11-11.11.15.09.mov