Skip to content

이선민 - 자판기 온보딩 프로젝트#19

Open
HelloHailie wants to merge 44 commits into
mainfrom
seonmin
Open

이선민 - 자판기 온보딩 프로젝트#19
HelloHailie wants to merge 44 commits into
mainfrom
seonmin

Conversation

@HelloHailie

@HelloHailie HelloHailie commented Nov 25, 2024

Copy link
Copy Markdown

1차 리뷰 후 todo 리스트

  • 린트 및 포매터 강제하도록 수정
  • 사용하지 않는 updateBalance 함수 제거
  • 자바스크립트에서 디자인 요소 하나하나 만들지 않고 template 사용
  • mdn input의 참고해서 valueAsNumber 알아보고 사용
  • enter키 사용기능은 form 태그에 submit 함수 사용해서 종속되지 않는 방법으로 웹 표준 방법 사용하기
  • 이벤트 리스너 내부 함수 어떤건 전역으로 사용하고 어떤건 아닌데 통일시키기. (추후 테스트를 위해서는 파라미터 사용)

추가 todo 리스트

  • proxy 사용해서 자동으로 트리거가 될 수 있도록 하기. 참고 링크
  • 테스트 진행을 위한 모듈화 작업
  • 테스트 진행

@HelloHailie HelloHailie added the WIP 아직 작업 중입니다 label Nov 25, 2024
@HelloHailie HelloHailie added Needs Review 리뷰받을 준비가 되면 추가해주세요 and removed WIP 아직 작업 중입니다 labels Nov 29, 2024
@HelloHailie HelloHailie added WIP 아직 작업 중입니다 and removed Needs Review 리뷰받을 준비가 되면 추가해주세요 labels Nov 30, 2024
- HTML 구조 개선: 정적 마크업으로 UI 구조 변경
- CSS 스타일 수정: 레이아웃 및 디스플레이 속성 조정
- JavaScript 코드 리팩토링:
  - DOM 요소 참조 방식 개선
@HelloHailie HelloHailie added Needs Review 리뷰받을 준비가 되면 추가해주세요 and removed WIP 아직 작업 중입니다 labels Nov 30, 2024
- 금액 입력 컨테이너를 form 요소로 변경하여 제출 시 기본 동작 방지
- '투입' 버튼을 form의 submit 타입으로 변경
- HTML에 상품 버튼 템플릿 추가
- JavaScript에서 템플릿을 활용한 상품 그리드 초기화 로직 개선
- DOM 조작 최소화로 성능 향상
- 입력값 파싱 방식 변경: Number.parseInt() 대신 valueAsNumber 속성 사용
- 유효성 검사 로직 개선: NaN 체크 추가
- 숫자가 아닌 문자 제거 정규식을 /[^0-9]/g에서 /\D/g로 변경
- initializeEventListeners 함수에 객체 구조 분해 할당 적용
- initialize 함수에서 필요한 요소만 전달하도록 수정
- 현재 잔액과 투입 금액의 합이 1억원을 초과하는 경우 처리
- JSDoc 스타일의 주석 추가로 함수 설명 및 매개변수 타입 명시
- 주요 객체와 함수에 대한 설명 주석 추가
Comment thread src/main.js Outdated
updateDisplayAmount(state.currentMoney);
break;
}
};

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@taggon
이벤트 처리하는 부분을 한 곳에서 처리해서 경우를 나눈 이유가 아래 코드가 중복되서 하나의 함수로 묶어서 진행했는데요, 이정도 규모이면 따로 풀어서 진행하는게 효율적인 방법인걸까요?

const target = e.target.closest('.product-button'); if (!target) return; const productId = Number.parseInt(target.dataset.productId); const product = PRODUCTS.find((product) => product.id === productId);

 const handleClick = (e) => {
  const target = e.target.closest('.product-button');
  if (!target) return;
  const productId = Number.parseInt(target.dataset.productId);
  const product = PRODUCTS.find((product) => product.id === productId);
  updateDisplayAmount(product.price);
  handleProductPurchase(product);
};

const handleMouseOut = (e) => {
  const target = e.target.closest('.product-button');
  if (!target) return;
  const productId = Number.parseInt(target.dataset.productId);
  const product = PRODUCTS.find((product) => product.id === productId);
  updateDisplayAmount(state.currentMoney);
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

이런 경우에도 저는 나누는 게 나중에 추적하기가 쉽다고 봐요. 다만 공통된 부분은 다시 별도의 함수로 만들 수 있습니다. 타입도 보고 이해하시라고 편의상 TS로 작성해볼게요.

function getProductFrom(element: HTMLElement) {
  const button = element?.closest('.product-button');
  const productId = Number.parseInt(button?.dataset.productId);
  const product = productId ? PRODUCTS.find(item => item.id === productId) : null;

  return product;
}

function handleClick(e: MouseEvent) {
  const product = getProductFrom(e.target);
  if (product) {
    updateDisplayAmount(product.price);
    handleProductPurchase(product);
  }
}

function handleMouseOut(e: MouseEvent) {
  const product = getProductFrom(e.target);
  if (product) {
    updateDisplayAmount(state.currentMoney);
  }
}

일단 이렇게 수정할 수 있을 것 같기는 한데 이 코드만 보면 handleMouseOut에서 product를 가져와야 할 이유가 안 보이네요.

@HelloHailie HelloHailie added Needs Review 리뷰받을 준비가 되면 추가해주세요 and removed WIP 아직 작업 중입니다 labels Dec 2, 2024
Comment thread src/main.js Outdated
updateDisplayAmount(product.price);
handleProductPurchase(product);
break;
case 'mouseout':

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

이 경우에는 mouseout 보다는 mouseleave가 더 맞을 겁니다. 그리고 addEventListener의 세 번째 인수를 true로 설정하셔야 할테고요. 차이가 뭘까요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

오! 궁금해서 찾아봤더니 차이가 명확하게 있네요!
mouseleave 이벤트는 요소의 경계를 완전히 벗어날 때만 발생해서 현재 제 코드는 부모 요소인 productGrid에 이벤트를 걸고 있는데, addEventListener의 세 번째 인수인 useCapture 옵션을 이벤트 캡처링 단계에서 이벤트를 처리한다고 true로 설정해서 하는 방법을 말씀주신 거네요. 이 방법대로 수정해보겠습니다 😃

@taggon taggon added Reviewed 리뷰를 마친 상태입니다 and removed Needs Review 리뷰받을 준비가 되면 추가해주세요 labels Dec 4, 2024
@HelloHailie HelloHailie added WIP 아직 작업 중입니다 and removed Reviewed 리뷰를 마친 상태입니다 labels Dec 4, 2024
- handleGridEvent 함수를 handleClick과 handleMouseLeave로 분리
- 제품 조회 로직을 getProductById 유틸 함수로 추출
- mouseout 이벤트를 mouseleave로 변경하여 이벤트 버블링 개선
- .gitignore 파일을 현대적인 구조로 정리
- pre-commit 훅을 lint-staged를 사용하도록 변경
- lint-staged 설정에 포맷팅, 린팅, 자동 스테이징 추가
- Proxy 객체를 사용하여 상태 변경 감지 로직 구현
- 금액 표시 업데이트 로직 중복 제거
- forEach를 for...of로 변경하여 반복문 가독성 개선
- product-template을 product-grid 내부로 이동하여 HTML 구조 개선
- 관련 컴포넌트들의 계층 구조를 더 명확하게 정리
- 기능별로 디렉토리 구조 재구성
  - dom: DOM 요소 조작 및 참조 관련 코드
  - features: 상품과 금액 관련 핵심 기능
  - store: 전역 상태 관리
  - utils: 포맷팅, 로깅 등 유틸리티 함수

- 관련 기능들을 단일 책임 원칙에 따라 모듈화
- 파일 경로 및 import 구문 정리
- moneyService: deductMoney 함수에서 불필요한 금액 검증 제거
- productService: validatePurchase 함수에서 중복 검증 제거
- Product.js → product.js로 파일명 컨벤션 통일
@HelloHailie HelloHailie added Needs Review 리뷰받을 준비가 되면 추가해주세요 and removed WIP 아직 작업 중입니다 labels Dec 7, 2024
@HelloHailie

Copy link
Copy Markdown
Author

@taggon 기존 작업에서는 테스트를 DOM 요소를 모킹하는 식으로 작성해야해서 아래와 같이 main.js 내 함수를 아래를 기준으로 나누어서 비즈니스 로직 부분만 테스트를 작성해보았습니다.

미진한 부분이 있다면 피드백 부탁드립니다. 🙇

  1. controllers/: UI 이벤트 핸들링
  2. data/: 정적 데이터
  3. dom/: DOM 요소 참조
  4. models/: 데이터 모델
  5. services/: 비즈니스 로직
  6. utils/: 유틸리티 함수들

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

Labels

Needs Review 리뷰받을 준비가 되면 추가해주세요

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants