-
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
[7팀 김원표] [Chapter 1-2] 프레임워크 없이 SPA 만들기 #33
Open
pitangland
wants to merge
20
commits into
hanghae-plus:main
Choose a base branch
from
pitangland:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains 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
심화과제를 대비하여 while로 선언했지만, 기본과제 흔적을 남겨놓기 위하여..
jungeun0712
reviewed
Dec 29, 2024
Comment on lines
+2
to
+5
// 특정 요소(key, element)에 대해 여러 핸들러(뭘 할건지)를 관리하기 위해 | ||
const eventHandlers = new Map(); | ||
// 이벤트 타입(key, eventType)별로 루트 요소에 리스너 등록, 발생한 이벤트 해당 핸들러로 전달 | ||
const rootEvent = new Map(); |
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.
이렇게 각 DOM 요소별, 루트 요소에 이벤트 타입별로 나눠서 관리하니 더 명확한거 같아요!! 생각 못한 부분인데 코드 잘 보고 갑니다!
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.
과제 체크포인트
기본과제
가상돔을 기반으로 렌더링하기
이벤트 위임
심화 과제
1) Diff 알고리즘 구현
2) 포스트 추가/좋아요 기능 구현
과제 셀프회고
처음에는 가상돔이 무엇인지, 어떻게 동작하는지 이해하는 것에만 시간이 많이 걸렸다. 특히, 이벤트 위임과 업데이트 로직을 구현하며 정말 많은 시행착오를 겪었지만, 이 과정에서 100퍼센트는 아니고 60퍼센트정도 이해한 것 같다. 가상돔의 본질적 개념을 이해할 수 있었고, 실제 장단점을 파악할 수 있었다.
기술적 성장
“normalizeVNode 함수에 문제가 있구나” 하고 알게된 것은 DOM 요소를 생성할 때, 타입이 함수이면 에러를 내야하는데 다시 정규화를 해주고 있었다. 결과적으로 올바르지 않은 DOM 요소가 생성되거나 예상치 못한 동작이 나타났다. 이러한 문제가 normalizeVNode 함수의 설계 결함에서 비롯되었음을 알게 되었다.
(같이 발견해준 팀원분들 너무 감사합니다… 7팀&10팀 최고!!!)
normalizeVNode.js를 살펴보자.
가상 노드를 표준화된 형태로 변환하는 역할인데, 일관된 데이터 구조를 사용할 수 있도록 해야한다.
vNode의 타입이 함수일 경우 해당 함수를 호출하여 반환된 결과를 재귀적으로 표준화한다.
그 외의 경우, vNode의 자식 요소들을 재귀적으로 표준화하고, null 또는 undefined 값을 필터링하여 반환한다.
바뀐코드는 모든 자식 노드를 재귀적으로 정규화하고, 정규화된 결과 중 유효하지 않은 노드를 제거하였다.
불필요한 평탄화 작업이라 children에 대한 처리가 강제적이었는데 수정된 코드는 필요한 시점에 정규화 및 필터링을 수행하도록 했다.
eventManger 함수가 가장 어려웠다. 이벤트 함수를 어딘가에 저장하고 삭제한 후 전부 가져와서 한 번에 root에 이벤트를 등록한다고 생각했는데 중복 등록 가능성이 있었다.
추가된 코드로 루트 리스너가 중복 등록되어 동일한 이벤트가 여러 번 호출되는 것을 방지하였다. 루트 요소에 한 번만 리스너를 등록하도록 보장하여 이벤트 위임 패턴의 최적화를 하였다.
이벤트 위임 문제였다. 이미 테스트 코드는 통과한 상태라 통과되면 끝이지라고 생각했던 곳에서 계속해서 오류가 나고 있었다. 다시 살펴보니 당연한 결과였다.
기존에는 if문 없었다. 이런 멍청한 짓을 하다니 다른 핸들러인 경우에만 제거했어야했는데 그냥 모두를 다 제거해버렸던 것이었다.
코드 품질
2주차의 코드 품질은 깔끔한 코드가 아닐지 몰라도 테스트를 통과했다는 사실에 너무 만족스럽다. 테스트코드를 하나씩 통과하려고 짠 코드이다보니 중복되는 조건문이 많았고 util로 사용했어도 괜찮지 않았을까 생각해보았다.
심화과제 중 포스트 기능을 구현하며 1주차에 했던 설계 관련 고민의 해결 실마리를 살짝 찾은 듯 했다. 다른 사람이 설계한 코드라도 관심사가 확실히 분리되어 있어 코드를 추가하기에, 확장하기에 불편함이 없었다. 이 부분을 참고하여 1주차의 리팩토링을 해보려한다.
학습 효과 분석
프레임워크를 사용하면 이런 개념을 알기 쉽지 않은데 직접 가상돔을 구현하며 브라우저 로딩 과정을 알 수 있었다. 개발을 독학한 입장으로 성능에 관하여 깊게 생각해볼 경험이 없었는데 어디서 가장 많이 성능을 잡아먹는지, 성능을 개선하는 방법이 무엇인지 알게되었다.
개념은 알아도 아직 코드로 구현하기에는 턱없이 부족한 것 같다. 특히, 이벤트 위임과 DOM 요소가 업데이트 됐을 때의 렌더링 과정에 대해 더 자세하게 디버깅하며 확인해보아야할 것 같다.
과제 피드백
프레임워크를 사용하지 않고 오로지 javascript로만 가상돔을 구현해볼 수 있는 경험이 좋았다.
리뷰 받고 싶은 내용
parentElement 존재 여부 체크와 같은 방어 로직들이 적절한 위치에 배치되어 있는지, 더 효율적인 처리 방법은 없는지 궁금합니다. 또한, null 체크가 적절한지, 혹시 위험부담은 없는지도 궁금합니다.
ex1) 원래는 방어 로직 없이도 테스트는 통과했지만, 콘솔에 TypeError가 발생하여 다음과 같은 코드를 추가해 해결했습니다.
ex2) 아래 코드가 없어도 실행 시 자연스럽게 에러가 발생하여 테스트는 통과됩니다. 하지만 함수형 컴포넌트 처리 시 발생하는 에러를 명시적으로 표현하기 위해 추가했는데, 이런 방식이 안전한지 궁금합니다.