과제 체크포인트
배포 링크
https://yuyeol.github.io/front_6th_chapter1-2/
기본과제
가상돔을 기반으로 렌더링하기
- createVNode 함수를 이용하여 vNode를 만든다.
- normalizeVNode 함수를 이용하여 vNode를 정규화한다.
- createElement 함수를 이용하여 vNode를 실제 DOM으로 만든다.
- 결과적으로, JSX를 실제 DOM으로 변환할 수 있도록 만들었다.
이벤트 위임
- 노드를 생성할 때 이벤트를 직접 등록하는게 아니라 이벤트 위임 방식으로 등록해야 한다
- 동적으로 추가된 요소에도 이벤트가 정상적으로 작동해야 한다
- 이벤트 핸들러가 제거되면 더 이상 호출되지 않아야 한다
심화 과제
Diff 알고리즘 구현
- 초기 렌더링이 올바르게 수행되어야 한다
- diff 알고리즘을 통해 변경된 부분만 업데이트해야 한다
- 새로운 요소를 추가하고 불필요한 요소를 제거해야 한다
- 요소의 속성만 변경되었을 때 요소를 재사용해야 한다
- 요소의 타입이 변경되었을 때 새로운 요소를 생성해야 한다
과제 셀프회고
코드 품질
-
Normalized 전후 기점의 VNode를 중점으로 타이핑 진행하였고 아래 내용과 같이 유형을 나누었습니다.
- VElement: Primitive가 아닌 VNode
- RawVNode: VElement 또는 RawPrimitive
- VNode: VElement 또는 Primitive
- RawPrimitive: string | number | boolean | null | undefined
- Primitive: string (normalize 되어 DOM 추가에 추가 될 값 )
- RawChild: 자녀 노드
- Child: normalize로 가공된 자녀노드
-
- updateChildren: 인덱스 기반으로 변경사항을 비교하여 updateElement를 실행시키는 책임을 담당합니다.
- updateProps: 개별 노드들의 props의 변경에 대한 책임을 담당합니다.
-
updateProps 로직 통합 초기 구현에서는 createElement와 updateElement 각각에 updateProps 로직을 작성했었습니다. 이후 createElement용 함수에는 prevProps가 없다는 점을 제외하고는 updateProps가 거의 동일한 동작을 하고 있기에 통합해도 좋겠다고 판단했습니다.
-
실행 흐름 상 일어날 수 없는 케이스에 대하여 error 처리 + type guard를 했습니다.
-
createElement – normalize 되지 않은 Custom component는 사용할 수 없습니다.
- JSX가 normalizeVNode를 거치면 Custom component는 모두 실제 DOM VNode로 풀려 있어야 합니다.
-
renderElement – 렌더링 할 vNode를 찾을 수 없습니다.
- normalize를 거친 vNode는 null | undefined를 리턴할 수 없습니다.
-
renderElement – updateElement 호출되려면 prevVNode가 존재해야 합니다.
- 리렌더 시 prevVNode는 비어있는 상황은 가정하지 않습니다. diff 알고리즘은 prev DOM이 반드시 필요합니다.
-
updateElement – Prev와 Current는 VElement여야 합니다.
- Primitive가 이미 걸러진 분기에 해당하므로 Prev와 Current는 VElement여야 합니다.
-
(element as any)[key]에서
any를 사용한 것은 건 의도가 명확합니다.- HTMLElement 타입 정의에는 disabled, checked, required처럼 자주 쓰는 필드만 선언되어 있고, key가 무엇으로 들어올지 컴파일 타임에 예상할 수 없으므로 이에 대한 타이핑 작업을 하기보다는 as any로 우회하였습니다.
- 다른 로직들의 타이핑에 영향을 주지 않아 국소적인 any 타입 단언은 안정성에서도 문제가 되지 않습니다.
-
-
이해한 학습내용을 기반으로 각 파일의 최상단에 동작원리를 간단하게 요약해두었습니다.
-
커밋 작성 단위에 대한 아쉬움이 있습니다.
- 모듈 단위로 구현 커밋을 남겼는데, 구현 + 리팩토링의 전 과정을 한 커밋에 두어서 고민한 흔적이 드러나지 않은것 같습니다.
학습 효과 분석 및 기술적 성장
기존에 경험해본 적 있던 VDOM의 DOM 교체과정, 리컨실러의 동작 원리를 복습해볼 수 있었던 시간이었습니다. 저 스스로를 솔직히 판단하자면 여전히 추상적으로 그려지는 영역이 많이 존재합니다. 그렇지만 이번 기회로 조금더 해상도를 높일 수 있는 기회가 되었습니다. 그리고 코치님께서 조언해주셨던 리액트로 Nextjs 만들어보기를 도전해볼 수 있는 계기가 되는 것 같습니다. 기술을 뜯어보고 그 메커니즘을 흉내 내어보는것만으로 큰 학습효과를 얻을 수 있다는 것을 이번 기회에 많이 실감했습니다.
과제 피드백
- 테스트의 존재와 미리 명확하게 모듈을 나누어주신 구조로 인해 AI 사용 시 과제를 꽤 쉽게 완료하는 경우가 많을 수도 있겠다는 생각이 들었습니다.
- 각각의 모듈 구현에 집중하면 되는 과제이다보니 의도적으로 프로젝트 전체를 파악하려는 노력을 하지 않는다면 학습하길 의도하신 전체 흐름을 이해하지 못하고 넘어가는 수강생도 존재할 것 같습니다.
- 이전에 이 과제와 유사하게 리액트를 모방한 구조를 만들어본 경험이 있습니다만, 코치님이 구성하신것처럼 체계적이지 못했기에 코치님의 과제를 분석하면서 정말 많은 인사이트를 얻어갈 수 있었습니다.
리뷰 받고 싶은 내용
-
제가 구현한 코드 중에서 코치님이라면 이렇게 작성하지 않았을텐데 라고 생각이되는 부분들이 있다면 알려주시면 감사하겠습니다. 1차적으로는 아래와 같은 내용들입니다.
- 이벤트 매니저에서 이벤트를 저장하고 사용하기 위해 채택한 자료구조의 활용이 적절한가
- 불필요한 재귀나 리소스를 낭비할만한 플로우가 보였는가
- 최대한 과제에 충실한 기능만 구현, 오버엔지니어링 되는 요소들을 분별해가며 제한적으로 구현했는데 실제로도 그러한가
-
변수명, 타입명, 주석 대신 가독성 좋은 코드 작성(학습용 주석 제외)을 지향하면서 과제를 수행하고 있습니다. 아쉬운 부분이 있다면 알려주시면 감사하겠습니다.
과제 피드백
안녕하세요 유열님! 2주차 과제 잘 진행해주셨네요 ㅎㅎ 고생하셨습니다.
테스트의 존재와 미리 명확하게 모듈을 나누어주신 구조로 인해 AI 사용 시 과제를 꽤 쉽게 완료하는 경우가 많을 수도 있겠다는 생각이 들었습니다.
반대로 생각하면, "이런 구조가 있으면 AI가 문제를 해결하기 쉽겠는데?" 라고 판단하고 앞으로 AI를 더 잘 활용하는 방법에 대한 인사이트가 되리라 생각해요. 이제는 AI를 활용해야 하는 시대라서... ㅋㅋ
각각의 모듈 구현에 집중하면 되는 과제이다보니 의도적으로 프로젝트 전체를 파악하려는 노력을 하지 않는다면 학습하길 의도하신 전체 흐름을 이해하지 못하고 넘어가는 수강생도 존재할 것 같습니다.
이 부분도 고민이 되는 지점 중에 하나인데요, 원래 이전 기수에는 새로운 기능을 추가하는 요구사항이 있었으나... 지난주 과제에 대한 피로도가 쌓여있으리라 생각하여 일부로 제외했답니다 ㅎㅎ
다음에는 꼭 넣어봐야겠어요!
- 이벤트 매니저에서 이벤트를 저장하고 사용하기 위해 채택한 자료구조의 활용이 적절한가
WeakMap, Map, Set 등 다양하게 사용해주셨네요! 다만 Map의 key가 string이여서, 굳이 Map을 사용할필요가 있을까? 라는 생각이 들어요. 단순 객체로 표현할 수도 있고..!?
- 불필요한 재귀나 리소스를 낭비할만한 플로우가 보였는가
쓱 살펴봤을 땐 크게 문제되는 부분은 없어보이네요!
- 최대한 과제에 충실한 기능만 구현, 오버엔지니어링 되는 요소들을 분별해가며 제한적으로 구현했는데 실제로도 그러한가
실무와 학습은 다를 수 있다고 생각해요. 실무에서는 효과적인 방식을 채택해야 하고, 학습에서는 효과적인 방식이 중요한게 아니라 많은 지식과 판단 근거를 습득하는게 중요해서요. 그래서 오버엔지니어링도 시도해보시면 좋답니다 ㅎㅎ
변수명, 타입명, 주석 대신 가독성 좋은 코드 작성(학습용 주석 제외)을 지향하면서 과제를 수행하고 있습니다. 아쉬운 부분이 있다면 알려주시면 감사하겠습니다.
질문해주신 것들이 다 포괄적인거라... 유열님이 작성한 코드나 생각의 흐름을 코드에 직접 코멘트를 남겨주시거나 하면 더 좋았을 것 같아요 ㅠㅠ
특히, 가독성 좋은 코드를 지향한다고 하셨는데 "이렇게 작성하면 가독성이 좋아! 이유는 ~~~ 라서 그래!" 라는 형태의 의견이 있으면 좋을 것 같아요. 지금은 "무슨 의도로 이렇게 한걸까?" 라고 제가 추측하면서 봐야 한답니다.. 시간이 몇배는 소모되는거죠 ㅎㅎ;