[4팀 김지혜] Chapter 1-1. 프레임워크 없이 SPA 만들기 - #72
Open
adds9810 wants to merge 45 commits into
Open
Conversation
fix: 목록 렌더링 로직 수정 및 테스트 케이스 대응 test: Vitest 통과를 위한 조건 분기 및 mock 반영
- 기존 객체형 컴포넌트를 클래스 기반으로 전환 - render 방식 수정으로 테스트 환경 호환성 확보 - 컴포넌트 구조 정리 및 상태 관리 방식 일원화
- 카테고리 클릭 시 필터링 기능 작동하도록 이벤트 핸들러 구현 - 사용자 인터렉션에 맞춘 UI 상태 변경 처리 추가 - 관련 E2E 테스트는 통과 확인했으나, 7. 카테고리 선택 항목의 Vitest는 실패 상태 지속 → DOM 상태 변경 타이밍 또는 async 처리 이슈로 추정되며, 원인 분석 중
- 상품 상세 페이지 기본 구조 구현 (/detail/:id) - 라우터 설정 및 홈(/)으로 이동하는 기능 추가 - 렌더링 이슈로 전체 테스트 중 '2. 상품 상세 - 장바구니 담기' 실패 발생 → 단위 테스트에서는 통과, 통합 시 렌더 타이밍 또는 상태 반영 문제로 추정됨
- URL 변경 감지를 위한 커스텀 이벤트 추가 - pushState 시 헤더 상태 즉시 반영 - popstate 이벤트와 함께 urlchange 이벤트 처리 - 상품 클릭 시 뒤로가기 버튼 즉시 표시
refactor(toast): 토스트 컴포넌트 동작 방식 개선 및 연동 최적화
- cartStore 구독 시 this.state 동기화 방식 개선 - 상태 변화 시 전체 모달 재렌더링으로 DOM 일관성 보장 - 장바구니 아이템 삭제 후 상태 불일치 문제 해결
- Cart 인스턴스 중복 생성 방지 및 모달 DOM 완전 제거/삽입 처리 - ESC 키, 오버레이, X 버튼 등 다양한 닫기 방식 정상 동작 보장 - cartStore 상태 변화에 따라 모달 UI가 정확히 동기화되도록 개선 - 이벤트 리스너 중복 방지 및 해제 로직 추가 - 수량 조절, 선택/삭제 등 장바구니 내 동작의 상태 반영 신뢰성 향상 - SPA 라우팅 시 이전 컴포넌트 destroy() 호출로 상태/이벤트 꼬임 방지 - 라우터 구조 개선으로 페이지 전환 시 UI 및 상태 일관성 강화
- Detail.js 관련상품 카드 스타일 수정 - Cart 컴포넌트 update() 시 헤더 아이템 개수 실시간 갱신 기능 추가
- Toast.js 오타 수정 - Header badge 동적 생성/제거 구현 - 장바구니 뱃지 테스트 통과를 위한 DOM 동기화 개선 - 불필요한 파일 삭제
- 자기 PR 초안 작성 - (home) debounce 시간 임시 수정 (추후 재수정 필요) - (detail) 관련 상품 로딩 타이머 관리 추가 - (detail) category4 속성 오타 수정
- Detail 컴포넌트 구조 개선 - 라우터에서 컴포넌트 관리 방식 수정 - 테스트 간 간섭 방지 로직 추가
- gh-pages 패키지 및 배포 스크립트(package.json) 추가 - 자동 배포를 위한 .github/workflows/deploy.yml 워크플로우 생성
- Pages 배포 방식 및 라우터 세팅 변경 - 환경에 맞는 BASE_PATH 및 라우팅 방식 적용 - 배포 구조 및 경로 처리 개선
BASE_PATH와 navigate 함수 import
홈 링크 href를 BASE_PATH로 설정
클릭 시 navigate('/')로 SPA 라우팅 처리
배포 환경에서도 홈 이동 정상 동작
router.js에서 BASE_PATH를 export하여 import 에러 수정 Header 등에서 BASE_PATH 정상 사용 가능
상품 클릭 시 /front_6th_chapter1-1/product/ID로 이동하도록 변경 새로고침 및 직접 접근 시 404 오류 방지
- 관련상품 클릭 시 /front_6th_chapter1-1/product/ID로 이동하도록 변경 - 새로고침 및 직접 접근 시 404 오류 방지
- 홈, 상세 등 모든 링크 클릭 시 navigate 함수 사용 - BASE_PATH 직접 사용 제거 및 SPA 라우팅 일관성 강화
- 브레드크럼 링크에서 navigate 함수 사용 - 불필요한 파일 정리
- router.js의 navigate 함수를 CustomEvent + router() 직접 호출로 수정 - Detail 페이지에서 navigate 함수 사용으로 중복 코드 제거 - BASE_PATH 처리 로직을 navigate 함수 내부로 통합 - 모든 환경에서 일관된 네비게이션 동작 보장
JunilHwang
force-pushed
the
main
branch
2 times, most recently
from
September 26, 2025 01:13
a90ad7b to
d5eb31b
Compare
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.
과제 체크포인트
배포 링크
https://adds9810.github.io/front_6th_chapter1-1/
기본과제
상품목록
상품 목록 로딩
상품 목록 조회
한 페이지에 보여질 상품 수 선택
상품 정렬 기능
무한 스크롤 페이지네이션
상품을 장바구니에 담기
상품 검색
카테고리 선택
카테고리 네비게이션
현재 상품 수 표시
장바구니
장바구니 모달
장바구니 수량 조절
장바구니 삭제
장바구니 선택 삭제
장바구니 전체 선택
장바구니 비우기
상품 상세
상품 클릭시 상세 페이지 이동
/product/{productId}형태로 변경된다상품 상세 페이지 기능
상품 상세 - 장바구니 담기
관련 상품 기능
상품 상세 페이지 내 네비게이션
사용자 피드백 시스템
토스트 메시지
심화과제
SPA 네비게이션 및 URL 관리
페이지 이동
상품 목록 - URL 쿼리 반영
상품 목록 - 새로고침 시 상태 유지
장바구니 - 새로고침 시 데이터 유지
상품 상세 - URL에 ID 반영
/product/{productId})상품 상세 - 새로고침시 유지
404 페이지
AI로 한 번 더 구현하기
과제 셀프회고
이번 과제를 통해 웹 개발의 중요한 흐름을 깨달을 수 있었습니다. 하드코딩이나 프레임워크로 퍼블리싱만 하던 것에서 벗어나, 실제로 동작하는 웹 애플리케이션을 처음부터 끝까지 구현해보면서 개발의 전체적인 과정을 이해하게 되었습니다.
특히 클래스 기반 컴포넌트 설계, 상태 관리, 라우팅 시스템 등 이전에는 개념적으로만 알던 것들을 직접 구현해보면서 기능 구현 방법을 익혔습니다. AI와 구글링의 도움으로 어려운 기능들도 하나씩 해결해나가면서 문제 해결 능력이 향상되었습니다.
다른 사람들의 코드를 보면서는 오히려 자신감이 더 떨어졌지만, 이는 개발하는 하나의 과정을 이해하고 앞으로 어떻게 생각하고 접근해야 할지에 대해 깊이 생각해보게 된 계기가 되었습니다. 각자 다른 방식으로 같은 문제를 해결하는 것을 보면서 "정답은 하나가 아니다"라는 것을 깨달았고, 내가 가진 장단점을 객관적으로 파악할 수 있었습니다.
하지만 테스트 통과에 급급해서 클린코드 구현을 소홀히 한 점이 아쉬웠습니다. 기능 구현에만 집중하다 보니 코드 중복이나 성능 최적화 같은 부분을 놓친 것 같습니다.
그래도 어려운 부분이 있을 때마다 여기저기 도움을 받을 수 있고, 다른 수강생들의 코드도 볼 수 있으며, 실시간 소통으로 문제를 보완해가는 과정은 정말 좋았습니다. 특히 테스트 코드를 통과시키기 위해 노력하면서 말로만 듣던 테스트가 실제로 내 코드를 검증하는 과정을 경험할 수 있어서 신기했습니다.
비록 기한 내 모든 테스트 통과는 못했지만, 이번 경험을 통해 개발에 대한 이해와 문제 해결 능력을 키울 수 있었다 생각합니다.
기술적 성장
class Header,class Cart처럼 각 기능을 독립적인 클래스로 분리해서 코드를 정리하는 방법을 배웠습니다. 특히constructor,render()같은 메서드들을 사용하면서 객체지향 프로그래밍의 기본 개념을 이해하게 되었습니다.cartStore에서 옵저버 패턴을 사용해서 데이터가 바뀔 때마다 화면이 자동으로 업데이트되도록 만들었습니다.subscribe,notify메서드를 직접 구현해보면서 Vue나 React가 내부적으로 어떻게 동작하는지 이해하게 되었습니다.popstate이벤트와pushState를 사용해서 실제 웹사이트처럼 동작하도록 구현한 것이 신기했습니다.vitest와@testing-library가 어떻게 동작하는지 이해하게 되었습니다. 내가 작성한 코드가 테스트 요구사항에 맞게 동작하는지 검증하는 과정이 신기하고 유익했습니다.자랑하고 싶은 코드
cartStore에서 장바구니에 상품을 추가하거나 삭제할 때마다 헤더의 숫자가 실시간으로 바뀌고, localStorage에 저장해서 새로고침해도 데이터가 유지되도록 만든 부분이 가장 만족스럽습니다. 옵저버 패턴을 활용해서 깔끔하게 상태 변화를 처리할 수 있었습니다.Home.js에서 스크롤이 페이지 하단에 도달하면 자동으로 더 많은 상품을 불러오는 기능을 구현했습니다.debounce함수를 사용해서 성능을 최적화하고, 로딩 상태를 표시해서 사용자 경험을 개선한 것이 좋았습니다.Cart.js에서 장바구니 모달을 만들 때 ESC 키, 배경 클릭, X 버튼 등 다양한 방법으로 닫을 수 있게 구현했습니다. 이벤트 리스너를 체계적으로 관리하고, 모달 상태에 따라 DOM을 동적으로 제어하는 부분이 복잡했지만 잘 작동해서 뿌듯했습니다.개선이 필요하다고 생각하는 코드
Cart.js의bindEventListeners()메서드에서 10개 이상의 이벤트 리스너를 개별적으로 추가하는 부분이 복잡합니다. 각 버튼마다 별도로 이벤트를 추가하는 것보다 이벤트 위임(Event Delegation)을 사용하면 더 간단하고 효율적일 것 같습니다.store.js에서increaseQuantity,decreaseQuantity같은 메서드들이 비슷한 패턴으로 배열을 조작하고 있습니다. 이런 중복된 로직을 하나의 공통 함수로 합치면 코드가 더 깔끔해질 것 같습니다.Home.js와Cart.js에서cartStore에 직접 의존하고 있어서 테스트하기 어렵고 재사용성이 떨어집니다. 의존성 주입이나 인터페이스를 사용해서 컴포넌트 간 결합도를 낮출 필요가 있습니다.학습 효과 분석
this키워드와 메서드 호출 방식을 이해하게 되었습니다.과제 피드백
this바인딩이나 메서드 호출 방식에서 많이 헷갈렸습니다. 특히 이벤트 리스너에서this가 가리키는 객체가 바뀌는 문제를 해결하는 데 시간이 오래 걸렸습니다.AI 활용 경험 공유하기
리뷰 받고 싶은 내용
Home.js와Cart.js에서cartStore에 직접 의존하고 있어서 테스트하기 어렵고 재사용성이 떨어집니다. 컴포넌트들이 서로 너무 밀접하게 연결되어 있어서 나중에 수정하기 어려울 것 같습니다. 컴포넌트들을 더 독립적으로 만들 수 있는 방법이 있을까요? 예를 들어 Cart 컴포넌트를 다른 프로젝트에서도 사용할 수 있도록 만들려면 어떻게 해야 할지 궁금합니다.Cart.js의bindEventListeners()메서드에서 10개 이상의 이벤트 리스너를 개별적으로 추가하고 있는데, 이벤트 위임을 사용해서 더 효율적으로 관리하는 방법이 있을까요? 특히data-product-id속성을 활용한 이벤트 위임 패턴을 적용하면 코드가 더 간단해질 것 같은데, 막상 하려니 떠오르지 않았습니다. 어떤 방식으로 구현하는 것이 좋을지 조언해 주시면 좋겠습니다.store.js에서increaseQuantity,decreaseQuantity,toggleItemSelection등의 메서드들이 비슷한 패턴으로 배열을 조작하고 있습니다. 이런 중복된 로직을 하나의 공통 함수(예:updateItem)로 합쳐서 코드를 더 간결하게 만들 수 있을까요? 그리고 배열을 매번 새로 만드는 것보다 불변성을 유지하면서 성능을 개선하는 방법이 있는지 궁금합니다.Cart.js의templateContent(),itemCountText()같은 함수명들이 직관성이 떨어지다고 예를 들어templateContent()를renderCartContent()로 바꾸는 것을 제안하는데 어떻게 생각하시는지 궁금합니다. 그리고 어떤 함수와 변수를 더 명확하게 이름 지을 수 있는 방법에 대해 조언받을 수 있을까요?