[4팀 김수민] Chapter 1-2. 프레임워크 없이 SPA 만들기#56
Conversation
|
공주님 코드 블럭 쓰실 때 ```javascript 이렇게 써 주시면 이쁘게 된답니다 |
2Estella
left a comment
There was a problem hiding this comment.
수민 공주님~ 2주차 과제 너무너무 고생하셨어요! ❤️❤️💗💗
개인적으로 회고가 너무 재밌어서 술술 읽혔어요 ㅎㅎㅎ
코드 구경 잘하고 갑니다!
다음주차도 화이팅 🫶🫶
There was a problem hiding this comment.
오 GitHub Pages 자동 배포 워크플로우까지 작성해주셨네요 👍
There was a problem hiding this comment.
전체적으로 이벤트 관리를 유연하게 설계하신 점이 매우 인상적이네요!
저는 WeakMap<요소, 핸들러> 형태로 구현했는데, 수민님 방식처럼 WeakMap<요소, Map<타입, Set<핸들러>>> 구조를 사용하면 “여러 핸들러” 시나리오를 자연스럽게 처리할 수 있겠다는 생각이 들었어요.
특히 하나의 요소에 동일한 이벤트 타입을 복수로 등록할 수 있게 한 부분이 참신한데요, 실제 프로젝트에서 이런 요구가 자주 발생하는 편인지도 궁금해요!
| let el = e.target; | ||
|
|
||
| export function removeEvent(element, eventType, handler) {} | ||
| while (el && el !== root.parentNode) { |
There was a problem hiding this comment.
위임 범위를 el !== root로 제한하지않고, 왜 root.parentNode까지 순회하도록 하셨는지 궁금해요!
There was a problem hiding this comment.
root까지 순회해야 한다고 생각해서 저렇게 작성했어요!
el === root 가 될 때까지만 순회하려구요ㅎㅎ
| const normalizeChildren = (children) => { | ||
| return isArray(children) ? children.map(normalizeVNode).filter((c) => !isEmptyString(c)) : normalizeVNode(children); | ||
| }; |
There was a problem hiding this comment.
normalizeVNode 내부의 배열 처리 로직과 normalizeChildren 함수의 로직이 거의 동일한 것 같아요! normalizeChildren를 제거해도 되지않을까요?
There was a problem hiding this comment.
앗 그러네요..! normalizeVNode(children)만 해도 되겠네요!ㅎㅎ 감사합니당
There was a problem hiding this comment.
전체적으로 diff 알고리즘을 단순하면서도 명료하게 구현하셨네요!
updateAttributes와 removeAttributes로 속성 변경과 제거 로직을 깔끔하게 분리해 가독성을 높인 점도 좋고, isTextNode, isEvent, isClassName 같은 유틸 함수를 활용해 조건 분기가 한눈에 쏙 들어오도록 정리한 부분도 좋은 것 같습니다!
|
안녕하세요~ 수민 공주님! 오하늘입니다. |
There was a problem hiding this comment.
공주님은 Weakmap을 사용하셔서
Weakmap(Element, Map(EventType, Set(Handler))) 이렇게 구성을 하셨었네요.. 저도 그런 생각을 했었습니다만..
handler 재사용 방식에 따라서 저는
const handler = (elementMap) => (event) => {
for (const [element, handlers] of elementMap.entries()) {
if (element === event.target || element.contains(event.target)) {
for (const handler of handlers) {
handler.call(element, event);
}
}
}
};이런 식으로 핸들러 함수를 따로 빼서 그 핸들러 함수를 add 하고 remove 하는 식으로 작업했습니다.
setupEventListeners에서 root에 addEvent어쩌구 하실 때 매번 새로 정의한 e => {...} 함수를 바로 넘겨주시는 람다를 사용한다면, 나중에 remove 할 때 동일한 함수? 참조?를 찾기가 어려워서 위처럼 핸들러를 따로 뺐었습니다.
제가 한 방식이 아닐 수도 있으니.. 그리고 제 리뷰가 틀렸을 수도 있으니.. 그냥 참고만 부탁드립니다.
|
수민님 코드가 아름다워서 살짝 눈이 멀었더요 항상 꼼꼼하게 과제하시는 거 같아서 마니 배움미다 1번 질문에 대해 ,, 저도 remove 어쩌구의 매개변수 때문에 의문이 들었던 부분인데요 2번! 둘 다 무거운 연산이 아니니까 아무거나 쓰자! 유지 보수 관점에서는 set으로 관리하는 게 조아보여요 |
과제 체크포인트
배포 링크
https://nimusmix.github.io/front_6th_chapter1-2/
기본과제
가상돔을 기반으로 렌더링하기
이벤트 위임
심화 과제
Diff 알고리즘 구현
과제 셀프회고
면접 단골 질문~~ 가상 돔~~ 직접 만들어볼 기회가 생길 줄 몰랐어요!
사실 지난 주 과제에 지쳐서 이번 주에는 컴퓨터 앞에 앉기가 두려웠는데요(..)
막상 과제를 시작하니 가상 돔이 어떤 과정을 통해 동작하는지,
그 안에서 함수들은 어떤 역할을 하고 있는지 알아가는 게 정말 재밌었습니다!
기술적 성장
Boolean attribute
Boolean attribute는 setAttribute로 할당하지 않고 DOM 프로퍼티에 직접 할당해야 한다는 사실을 알게 되었습니다.
el.checked = true/false,el.selected = true/false식으로 처리해야 실제 요소의 상태가 즉시 반영되고,removeAttribute로 완전히 제거할 수 있어 렌더링과 자바스크립트 로직이 완전히 일치한다는 것을 알게 되었습니다.
(질문)
언젠가 실무에서
<div readOnly></div>이런 식으로 코드를 짠 적이 있어요.그 때 사수가
readOnly={true}이렇게 항상 명시해주는 게 좋다고 말씀해주셨어요.어.. 그런데 오늘 보니까 어떤 의도로 그렇게 말씀하신 건지 잘 이해가 안 갑니다..!!!
WeakMap
eventManager에서 event를 저장하기 위한 자료구조로 WeakMap을 사용했습니다.
객체가 메모리에서 없어지면 자동으로 가비지 컬렉션이 된다는 점이 흥미로웠어요.
특히 dom에서 사라지면 unmount 되기 때문에 딱 맞는 자료구조라고 생각했습니다.
적절한 자료구조를 쓰는 것만으로 손으로 쓰는 코드를 얼마나 줄일 수 있던지!
자료구조의 중요성에 대해 알 수 있었던 시간이었습니다. ><
가상 돔 동작 과정
createVNode,normalizeVNode등 각 함수들이 어떤 역할을 하는지 알 수 있었습니다.그 과정에서 몇 가지 의문이 생기기도 했는데요. 그 질문들은 아래와 같았습니다!
1 . createVNode에서 왜 자식을 평탄화(flatten)해야 하지? 어떤 경우에 중첩되는 거지?
-> 아래와 같은 경우가 흔하게 발생한다!
이 경우 평탄화하지 않는다면 vNode.children에 중첩 배열이 생기고, 이후에 재귀적으로 순회하거나 비교하기 어려워진다.
그래서 children.flat(Infinity)로 평탄화해서 한 번에 처리 가능한 배열로 만들어줘야 한다.
-> createVNode를 거치지 않고 직접 값이 들어오는 경우가 있다.
위 코드는 결국
createVNode('div', null, 'Hello', createVNode('span', null, 'World'))으로 파싱되기 때문에,children 배열에 'Hello' 같은 순수 문자열이 들어올 수 있다.
또한, 사용자 정의 컴포넌트가 반환하는 값이 string, number, null일 수도 있다.
코드 품질
학습 효과 분석
이렇게 바닐라 자바스크립트로 가상 돔을 만들어 보니까, 과정을 이해하면 다 논리적으로 이해가 되는구나~ 깨닫게 됐어요
면접 질문에 대한 답을 달달 외우기 보다 이렇게 공부하면 좋겠다!는 생각이 들었습니다.
과제 피드백
이번 과제는 구조적으로 틀이 짜져 있어서 너무나 마음이 편안했습니다..!!
과제 제출이 4시간 남은 시점에 PR을 쓰면서 이런 말 웃기긴 하지만(ㅋㅋ)
선택 과제로 좀 더 deep한 주제가 주어졌어도 좋을 것 같아요.
회사 사람한테 자바스크립트로 가상 돔 만든다고 하니까
Reconciliation 구현하는 게 어려울 거다, 제약 조건(예를 들면 react의 key) 같은 것을 두는 게 편할 거다
라고 이야기해서 좀 긴장했는데
그 부분을 경험하지 못해서 좋으면서 아쉬우면서 다행이면서 궁금합니다!
(물론 난이도가 엄청 높다고 들었어요! 나왔으면 울었을지도 흑흑)
리뷰 받고 싶은 내용
바닐라 자바스크립트로 가능한 것은 알고 있습니다만, 리액트의 경우에는 한 이벤트에 여러 개의 handler가 전달되지는 않으니..
이번 과제에서도 하나만 받게 했다가 remove 시 handler를 쓸 데가 없어서 (..) 수정했었습니다!
다른 친구들 코드를 보니 미리 constant로 선언해두고 쓰는 경우가 많더라구요.
constant로 선언해두고 써도 Array의 크기가 크지 않아 메모리, 연산 측면에서도 유의미한 차이는 나지 않을 거라고 생각하는데,
이런 경우에는 그냥 아무거나 (!!) 쓰면 될까요?