[2단계 - 웹 기반 로또 게임] 해니 미션 제출합니다.#474
Conversation
Co-authored-by: binggwa <qudrhks317@gmail.com>
eastroots92
left a comment
There was a problem hiding this comment.
안녕하세요 해니.
고민의 흐름을 잘 정리하여 적어주셔서 어떤 고민을 하시며 개발을 하셨는지 잘 알 수 있었어요.
자잘자잘한 피드백 보다 큰 맥락에서 고민해보시면 좋을 내용이 있어 코멘트 남겨 두었어요!
이번 리뷰를 통해 논의하고 싶은 부분
AI 활용과 학습 방식에 대한 고민
이 부분은 앞으로 어떻게 바뀔지 몰라 조금 더 조심스러운 부분은 있지만 지금은 학습의 목적이 있기 때문에 기본 개념을 직접 구현하며 공부하는 방식을 조금 더 권장드리고 싶어요.
다만 이 과정에서 생기는 궁금증이나 막히는 것을 과거에는 구글링을 했다면 AI에게 내가 이해한 것이 맞는지? 더 나은 방법이 있는지 등등을 물어보는 방식으로 해소하구요.
아직은 과도기 적인 측면이 크고, 결국 큰 맥락에 대한 이해를 위해서 학습은 필요하다고 생각해요.
시맨틱 태그와 네이밍
제가 네이밍에 대해선 온전히 이해하지 못했어요.
변수명과 같은 내용이라면 크게 이해하는데 어려움을 느끼진 않았어요!
시멘틱 태그의 경우 100% 잘 지켰다고 하긴 어렵지만 최소한의 지킬 요소들은 잘 지켰다고 생각해요.
사실 저도 시맨틱 태그를 100% 잘 챙기진 않는 편인데요.
과거 제가 학습 할 땐 시맨틱 태그를 잘 지키는 사이트 (ex. 애플, mdn 등)에선 어떻게 했었는지 참고했던 것 같아요.
만약 지금 학습한다면 한번 스스로 해보고 AI 피드백을 받는 방식으로 진행해볼 것 같네요!
Figma와 CSS 구현 차이
오 이 부분도 제가 온전히 이해하지 못했는데요!
추측을 해보자면 width의 가변성 때문일 것이라 생각하는데 맞을까요?
만약 맞다면 반응형 웹에 대한 개념과 감각을 익히는 것이 필요해요. 상황에 따라 디자이너 분이 잘 디자인을 잡아주신다면 문제가 없지만 결국 엔지니어도 어디는 고정값을 써야하고 어디는 유동적인 값을 써야하는지? 판단이 필요하기 때문이에요.
이 외에 만약 소숫점 단위의 px 값이 나온다면 이 부분은 디자이너분에게 수정해달라고 하고 있어요. 픽셀 단위에서 소수점은 OS나 브라우저 등등에 따라 차이가 있을 수 있기 때문이에요.
HTML / CSS 구조 분리
이 부분은 제가 직접 답변하기보다 SPA와 번들링 관련하여 공부해보시는 것을 추천해요.
더 엄밀히는 웹 렌더링의 변천사를 살펴보시며 왜 이렇게 바뀌었을까? 를 고민해보시면 좋겠어요.
지금 이스타가 고민하신 것 처럼 처음에는 단순히 하나의 html, css 파일로 시작했을 텐데 점점 규모가 커지고 요구사항이 많아지며 지금의 React와 같은 방식이 나왔기 때문이에요.
(다만 이게 무조건 React 같은 방식이 좋다는 것은 아니고 상황에 따라 적절한 선택이 필요해요)
CSS 또한 그동안 어떻게 변화했을까 찾아보시면 좋을 것 같아요!
index.js 구조
해당 부분의 경우 별도 코멘트 남겼어요!
입력 처리 시점
이 부분은 정답이 없는 것 같아요.
어떤 사용자 경험을 가져갈 것이냐, 어느정도나 디테일을 신경쓸 것이냐에 따라 달라지기 때문이에요.
일부의 경우 실시간으로 validate를 처리하기도 하고 (대표적인 케이스 회원가입 - 비밀번호, 비밀번호 확인) 일부의 경우 버튼 클릭 시 validate를 처리하기도 해요 (대표적인 케이스 로그인)
이 부분은 엔지니어링 적인 가성비도 따지지만 사용자 경험 측면도 복합적이라 지금 상황에 무엇이 좋은지에 따라 달라져요!
DOM 요소 표시 / 숨김 처리
오 이 부분은 display, visibility, opacity가 각각 어떻게 동작하는지? 렌더링 관점, css 처리 관점에서 한번 찾아보시면 좋겠어요.
제가 답변 드릴 수도 있지만 이 이해를 알고 계시면 스스로 어떨때 뭘 쓰면 좋을지 더 판단이 잘 될 것 같아서에요!
고생하셨습니다!!
src/step2-index.js
Outdated
| let lottos = []; | ||
| let purchasePrice = 0; |
There was a problem hiding this comment.
질문!
혹시 JS의 원시값과 참조값의 차이에 대해 알고 계신가요!?
이 둘의 차이를 살펴보고 이 부분에서 개선 할 부분이 있다면 스윽 개선해보시면 좋겠어요.
추가로 요구사항에서 const만 사용한다라고 명시되어있던 것으로 기억하는데! const만 사용해볼 수 있을까요!?
There was a problem hiding this comment.
아하! 말씀해주신 원시값과 참조값의 차이를 다시 살펴보니, 참조값 역시 const로 선언하더라도 내부 상태는 변경될 수 있다는 점을 인지하게 되었습니다.
이를 바탕으로, 단순히 let 대신 const를 사용하는 것보다 상태를 한 곳에서 관리하는 것이 더 중요하다고 판단했습니다. 그래서 LottoController 내부에 상태(#lottos, #purchasePrice)를 캡슐화하여 외부의 직접 접근을 차단하고, 상태 변경은 컨트롤러 내부의 메서드를 통해서만 이루어지도록 구조를 개선했습니다.
추가로, 함수 내부의 지역 변수는 모두 const를 사용해 불변성을 유지하고 예기치 못한 재할당을 방지했습니다. 클래스 필드는 문법상 const를 사용할 수 없기 때문에, 프라이빗 필드(#)를 활용해 캡슐화를 진행하였습니다.
src/View/OutputView.js
Outdated
| }, | ||
|
|
||
| printErrorMessage(errorMessage) { | ||
| Console.print(errorMessage); |
There was a problem hiding this comment.
기존 콘솔 기반 로또 게임에서 사용하던 로직이 남아있던 것 같습니다.
기존에는 OutputView에서 에러 메시지를 콘솔에 출력했지만, 현재는 validator에서 에러 처리를 담당하도록 구조를 변경하면서 중복되는 콘솔 출력 로직을 제거했습니다.
src/View/OutputView.js
Outdated
| lottosHtml += ` | ||
| <li class="lotto-item"> | ||
| <span class="emoji">🎟️</span> | ||
| <span id = "lotto">${lotto.toString().replace(/^\[|\]$/g, "")}</span> |
There was a problem hiding this comment.
P2 동일 id가 여러 요소에 반복 사용
로또가 여러 장 구매되면, id="lotto"가 반복 생성돼요. HTML에서 id는 페이지 내에서 유일해야 해요.
There was a problem hiding this comment.
반복 렌더링되는 요소에 id를 사용하면서 DOM 내 고유성 규칙을 깨고 있었던 점을 확인했습니다.
해당 부분을 class="lotto"로 수정하여 여러 요소에 안전하게 적용되도록 변경했습니다.
src/step2-index.js
Outdated
| @@ -2,3 +2,116 @@ | |||
| * step 2의 시작점이 되는 파일입니다. | |||
There was a problem hiding this comment.
P2 모든 로직이 한 파일에 집중되어 있어요
현재 step2-index 하나의 파일에서 DOM 선택, 이벤트 바인딩, 비즈니스 로직 호출, 에러 처리, UI 상태 변경을 모두 관리하고 있어요.
과제의 목표였던 도메인과 UI의 관심사 분리 관점에서 개선해보시면 좋겠어요.
예를 들어:
- 이벤트 핸들러를 별도 함수로 분리
- DOM 조작 부분을 OutputView에 위임
- 입력값 수집 부분을 InputView에 위임
같은 방향으로 개선 해볼 수 있지 않을까 싶어요!
There was a problem hiding this comment.
제안해주신 도메인과 UI의 관심사 분리 원칙을 반영하여 프로젝트 구조를 개선했습니다!
index.js에 집중되어 있던 이벤트 처리와 흐름 제어를 LottoController로 분리하였고,
DOM 조작은 OutputView, 사용자 입력 처리는 InputView가 담당하도록 역할을 명확히 나누었습니다.
index.css
Outdated
| font-size: 15px; | ||
| } | ||
|
|
||
| #winning-number-input-1 { |
There was a problem hiding this comment.
P2; 질문
#winning-number-input- 1 ... 6 까지 스타일의 반복으로 보여지는데 이렇게 한 이유가 있을까요?
There was a problem hiding this comment.
각 input을 개별적으로 식별하기 위해, id를 부여하는 과정에서 스타일도 함께 분리하여 작성했습니다! 다시보니 추후 입력창의 개수가 변하거나 디자인이 바뀔 때 모든 ID를 일일이 수정해야 하는 유지보수의 어려움이 있을 것 같다고 판단했습니다.
당첨 번호 input에 동일한 스타일이 반복되고 있어 공통 클래스로 분리하여 중복을 제거했습니다.
index.html
Outdated
| <p id="priceText">구입할 금액을 입력해주세요.</p> | ||
|
|
||
| <div class="purchase-row"> | ||
| <input id="inputPrice" placeholder="금액" /> |
There was a problem hiding this comment.
P3; type 속성 누락
모든 에 type 속성이 없어요. 기본값은 type="text"이지만, 금액 입력에는 type="number", 로또 번호 입력에도 type="number"를 명시하면 숫자 입력만 강제하고 모바일 페이지에서 숫자 키패드가 나오게 돼요!
There was a problem hiding this comment.
type을 number로 지정하여 숫자 입력만 가능하도록 개선했습니다!
index.html
Outdated
| <title>🎱 행운의 로또</title> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <link rel="stylesheet" href="./index.css" /> | ||
| <title>Document</title> |
There was a problem hiding this comment.
앗, 말씀해주셔서 감사합니다!
<title> 태그가 중복되어 있어 불필요한 <title>Document</title>를 제거했습니다.
src/View/OutputView.js
Outdated
| </li>`; | ||
| }); | ||
|
|
||
| lottoList.innerHTML = lottosHtml; |
There was a problem hiding this comment.
P3 innerHTML 사용 주의
innerHTML은 문자열을 직접 DOM에 삽입하는데, 만약 사용자 입력이 포함되면 XSS공격에 취약해질 수 있어요.
현재는 사용자 입력이 직접 들어가지 않아서 당장 위험하지는 않지만, 습관적으로 document.createElement와 textContent를 사용하는 것이 더 안전해요.
There was a problem hiding this comment.
오! innerHTML을 사용하는 과정에서 사용자 입력이 포함될 경우 XSS에 취약해질 수 있었군요..간과하고 있었네요
문자열 기반 DOM 삽입을 제거하고, createElement와 textContent를 활용하는 방식으로 수정하여 보다 안전하게 렌더링하도록 개선했습니다.
Co-authored-by: Root Lee <eastroots92@gmail.com>
|
@eastroots92 안녕하세요, 루트! 테코톡 준비와 원정대 활동이 겹쳐 리뷰 반영이 조금 늦어졌습니다.🥹 이번 리뷰를 반영하며 다음과 같은 방향으로 개선했습니다.
이를 통해, step2-index.js에는 컨트롤러 실행 코드만 남도록 단순화했습니다.
상태값을 전역 let 변수로 두는 대신, 컨트롤러 내부의 프라이빗 필드로 관리하도록 변경했습니다.
리팩토링을 진행하면서 궁금한 점이 생겨 질문드립니다. DOM에 접근할 때마다 매번 DOM 트리를 탐색하는 방식이 적절할까요? 현재는 필요한 시점마다 다시 한번 꼼꼼한 리뷰 감사드립니다. 😊 |
eastroots92
left a comment
There was a problem hiding this comment.
안녕하세요 해니
바쁜 일정 속에서도 제가 남긴 피드백을 고민하고 적용해주셔서 감사해요.
이제 다음 미션으로 넘어가기 위해 코드 머지를 하려고 해요.
질문에 대한 답변은 제일 하단에 남겨둘게요!
열정 넘치는 모습에 자극도 많이 받고 좋았습니다. 화이팅이에요!
고생하셨습니다!!
질문에 대한 답변
질문. DOM에 접근할 때마다 매번 DOM 트리를 탐색하는 방식이 적절할까요?
이 질문의 경우 상황에 따라 달라요. 단순히 매번 조회하는 것만 보면 문제가 있는 것 처럼 보이지만 항상 나쁘다고 생각하진 않아요. 상황에 따라선 매번 조회해야 하는 상황도 있구요.
사실 지금정도 기능에선 매번 조회하는게 큰 문제가 되지 않아요. 그렇기에 크게 고민하지 않으셔도 될 것 같아요.
일반적인 경우 조회 빈도, 시점, Dom 변경 가능성에 따라 판단하는 것 같아요.
만약 한두번만 쓰이거나, DOM이 자주 교체되거나(특정 요소가 다시 렌더링되거나 제거 후 재생성되는 케이스), 항상 최신 상태의 요소를 찾아야 하는 경우에는 매번 필요할 때 마다 새로 갱신하는 것이 좋아요.
반대로 자주 사용되는데 요소의 변경이 없는 경우 참조값을 변수로 관리하고 해당 값을 넘겨주는 방식으로 풀어 볼 수 있을 것 같아요.
학습 목표
이번 미션을 통해 다음과 같은 학습 경험들을 쌓는 것을 목표로 합니다.
제출 전 체크 리스트
리뷰 요청 & 논의하고 싶은 내용
UI 레이아웃 다이어그램
1) 이번 단계에서 가장 많이 고민했던 문제와 해결 과정에서 배운 점
사용자 입장에서 수익률이 마이너스로 표시되면 결과를 직관적으로 이해하기 어려울 수 있다고 생각했습니다. 따라서 당첨 금액을 기준으로 수익률을 표현하는 방식이 더 직관적이라고 판단했습니다. 예를 들어 10,000원을 구매했지만 당첨 금액이 없다면 수익률이 0%로 표시되도록 수정했습니다.
처음에는 JavaScript가 HTML을 어떻게 활용하고 조작하는지 감이 잘 잡히지 않았습니다. 하지만 이벤트가 발생했을 때 JavaScript가 DOM API를 통해 HTML 요소를 선택하고 내용을 변경하면서 화면이 업데이트된다는 흐름을 이해할 수 있었습니다.
이 과정에서 DOM API를 직접 사용해 보며 JavaScript가 HTML을 효율적으로 조작하는 방식에 대해 이해할 수 있었습니다.
2) 이번 리뷰를 통해 논의하고 싶은 부분
안녕하세요, 루트! 😊
이번에도 제 미션을 리뷰해주셔서 감사합니다.
궁금한 점이 조금 많습니다 ㅎㅎ 잘 부탁드립니다!
이번 step2 미션에서는 UI와 도메인 로직을 최대한 분리하고, 도메인 로직을 수정하지 않은 상태에서 UI를 구현하는 것에 중점을 두었습니다. 또한 사용자가 화면을 보았을 때 직관적으로 이해할 수 있는 UI를 만들기 위해 노력했습니다.
구현을 하면서 몇 가지 궁금한 점이 생겨 아래에 질문을 남깁니다.
1. AI 활용과 학습 방식에 대한 고민
AI를 사용하지 않고 구현하려다 보니 생각보다 시간이 많이 걸렸습니다. 웹 구현이 익숙하지 않은 상태라 진도가 느린 것도 있었습니다.
하지만 미션을 마친 뒤 AI를 사용해보니 5분 만에 UI를 생성해주는 모습을 보고 놀랐습니다.
이런 환경에서 웹의 기본 개념을 직접 구현하며 공부하는 방식이 여전히 의미 있는 학습 방법인지, 혹은 AI를 적극적으로 활용하는 방향이 더 좋은지에 대해 조언을 듣고 싶습니다.
2. 시맨틱 태그와 네이밍
시맨틱 태그를 활용하여 각 요소의 의미가 잘 드러나도록 마크업을 작성하려고 노력했습니다.
다만 제가 작성한 네이밍이 적절한지 확신이 서지 않습니다. 시맨틱한 구조를 설계할 때 참고할 만한 기준이나 네이밍 방식이 있다면 알고 싶습니다.
3. Figma와 CSS 구현 차이
협업 상황에서는 Figma 시안을 기반으로 UI를 구현하게 될 텐데, 실제로 구현하다 보니 Figma의 수치와 CSS가 정확히 일치하지 않는 경우가 있는 것 같습니다.
실무에서는 이런 차이를 어떤 기준으로 맞추는지 궁금합니다.
4. HTML / CSS 구조 분리
현재는 HTML과 CSS를 각각 하나의 파일로 작성했는데, 코드가 길어지다 보니 전체 구조를 한 번에 파악하기가 조금 어렵다는 느낌이 들었습니다.
실무에서는 보통 어떤 기준으로 파일이나 모듈을 분리하는지, 혹은 구조를 나눌 때 참고할 만한 방법이 있다면 알고 싶습니다.
5. index.js 구조
현재 index.js에는 실행 흐름을 두고, View 로직은 별도의 파일로 분리하려고 했습니다.
다만 구조적으로 index.js가 너무 많은 역할을 하고 있지는 않은지, 그리고 View와의 역할 분리가 적절하게 이루어졌는지 궁금합니다.
⭐ 특히 궁금한 질문 !!
6. ⭐ 입력 처리 시점
사용자의 입력을 즉시 검증하는 방식과 버튼 클릭 시 한 번에 검증하는 방식 중 어떤 방식을 사용하는 것이 더 적절한지 고민이 되었습니다.
로직이 복잡해질 것 같아 이번 미션에서는 즉시 검증 방식까지는 구현하지 못했지만, 실무에서는 상황에 따라 입력 검증 시점을 어떻게 결정하는지 기준이 있는지 궁금합니다.
7. ⭐ DOM 요소 표시 / 숨김 처리
특정 DOM 요소를 보이거나 숨길 때 display, visibility, opacity 등 다양한 방법이 있는 것으로 알고 있습니다.
실무에서는 이러한 방식들 중 어떤 기준으로 방법을 선택하는지 궁금합니다. 또한 DOM 조작 경험이 많지 않아서 느끼는 부분일 수도 있지만, 이러한 방식 중 일반적으로 권장되는 패턴이나 관례가 있는지도 알고 싶습니다.
✅ 리뷰어 체크 포인트
1단계
2단계