-
Notifications
You must be signed in to change notification settings - Fork 65
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
[6팀 소수지] [Chapter 1-2] 프레임워크 없이 SPA 만들기 #47
base: main
Are you sure you want to change the base?
Conversation
eventManager.js에서 eventListeners의 키가 eventType이네요(onClick같은)! 저는 element를 키로 잡았었는데, 이렇게도 할 수 있네요. 뭔가 이게 더 효율적인것 같은 느낌입니당 이번주도 수고하셨습니당~ |
Object.entries(props).forEach(([attr, value]) => { | ||
if (attr.startsWith("on") && typeof value === "function") { | ||
const eventType = attr.toLowerCase().slice(2); | ||
addEvent($el, eventType, value); | ||
} else if (attr === "className") { | ||
$el.setAttribute("class", value); | ||
} else { |
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.
크게 중요하지는 않을 것 같지만 리뷰 남겨 봅니다...!
현재 taillwind를 사용해서 css를 다루다 보니 각 element에 className이 더 자주 사용되지 않을까 라는 생각이 듭니다!
그래서 조건문 비교를 attr === 'className'을 가장 처음에 비교하는게 더 좋지 않을까? 라는 생각을 해봤습니다 ㅎㅎ
if (attr === "className") {
$el.setAttribute("class", value);
} else if (attr.startsWith("on") && typeof value === "function") {
const eventType = attr.toLowerCase().slice(2);
addEvent($el, eventType, value);
}
이번주 과제도 고생 많으셨습니다 :)
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.
앗 근데 생각 해보니 의미가 없을것 같네요....ㅎㅎㅎ
} | ||
|
||
export function setupEventListeners(root) { | ||
if (!root) return; |
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.
오호! early return!
|
||
return { | ||
...vNode, | ||
children: children.map(normalizeVNode).filter(Boolean), |
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.
filter(Boolean)은 JavaScript에서 truthy한 값만 남기기 위한 필터링 방법이라고 하네요! (처음 알았어요) 깔끔한 처리인 것 같습니다.
수지님 과제 하시느라 넘 고생 많으셨어요~!
과제 체크포인트
기본과제
가상돔을 기반으로 렌더링하기
이벤트 위임
심화 과제
1) Diff 알고리즘 구현
2) 포스트 추가/좋아요 기능 구현
과제 셀프회고
기술적 성장
VirtualDOM
VirtualDOM은 React의 핵심 개념 중 하나로 메모리 상에 존재하는 DOM의 가벼운 복사본입니다.
React는 상태 변경 시 새로운 VirtualDOM 트리를 생성하고, 이전 트리와 비교하여 변경사항을 파악합니다.
이 과정을 통해 실제 DOM 조작을 최소화하여 성능을 개선합니다.
VirtualDOM의 구조
가상 돔은 실제 돔의 형태를 본따 만든 객체 덩어리입니다.
diff 알고리즘
diff는 두 개의 파일 또는 문서 간의 차이점을 식별하는 알고리즘 또는 도구를 의미합니다.
원본과 수정된 버전 사이의 변경 내용을 탐지하고 추가된 내용, 제거된 내용, 수정된 내용 등을 식별합니다.
diff 알고리즘 과정
4-1. 변경된 속성이 없으면 바로 사용
4-2. 변경된 속성이 있으면 해당 속성을 업데이트
테스트 코드 중 "이벤트 핸들러가 제거되면 더 이상 호출되지 않는다." 라는 항목에서 계속해서 에러가 발생했었습니다.
eventManager
에removeEvent
부분에 문제가 지속해서 발생하는 것 같아 수정에 수정을 거듭했습니다.처음에는
eventListeners
에서 특정element
를 키로 하여 이벤트와 핸들러를 관리하고,수정한 코드에서는
eventListeners
에서eventType
을 키로 사용하여 이벤트 타입 별로 요소와 핸들러를 관리하도록 변경했습니다.처음 코드에서
eventListeners
가element
를 중심으로 관리되었기 때문에,동일한
eventType
을 여러element
을 사용하거나 삭제할 때 잘못된 핸들러를 삭제하거나 충돌이 발생할 수 있었습니다.이로 인해
eventType
중심으로 설계를 변경하여 문제 해결을 할 수 있었습니다.코드 품질
updateElement
부분에서 diff 알고리즘을 사용하여 변경된 속성이나 태그를 업데이트하는 과정을 구현한 부분입니다.먼저 어떤 로직을 만들어야하는지 정의하고, 하나씩 코드를 구성하여 내용을 정리했습니다.
학습 효과 분석
VirtualDOM을 구현하는 과정
createVNode
: 실제 돔을 가상 돔으로 만들기normalizeVNode
: 가상 노도를 표준화된 형태로 변환, 다양한 타입을 처리하여 일관된 형식의 가상노드를 반환하는 과정createElement
: 가상 돔을 실제 돔으로 변환updateElement
: 모든 태그 내용들을 비교하여 변경된 부분에 대한 수정/추가/삭제eventManager
: 렌더링 된 돔에 이벤트를 등록renderElement
: 상태가 바뀐 돔을 렌더링Map과 WeakMap의 차이점
Map
key
로 모든 값을 사용할 수 있습니다.key
가 될 수 있습니다.delete
를 호출하지 않는 한 key-value 쌍은 메모리에 유지됩니다.for..of
,map
메서드를 통해 반복이 가능합니다.size
프로퍼티 key-value 쌍의 개수 확인이 가능합니다.WeakMap
key
는 반드시 객체여야만 합니다.key
로 사용할 수 없습니다.size
프로퍼티가 없습니다.당장 실무에 적용하기 보다는 React의 Virtual DOM의 개념과 작동 방식을 조금이나마 이해할 수 있어서
React를 좀 더 잘 활용하고 사용할 수 있는 계기가 된 것 같습니다.
리뷰 받고 싶은 내용