-
Notifications
You must be signed in to change notification settings - Fork 49
[1팀 천진아] Chapter2-2. 나만의 React 만들기 #7
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
Open
totter15
wants to merge
17
commits into
hanghae-plus:main
Choose a base branch
from
totter15: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 hidden or 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
- 이벤트 핸들러 제거 로직 추가 (removeEventListener) - 타입 정보를 포함한 경로 생성으로 컴포넌트 경로 유지 - 타입 기반 자식 매칭으로 중첩 컴포넌트 상태 독립성 보장 - 일반 HTML 속성 설정 활성화 - cleanupUnusedHooks 구현
- key 기반 자식 재조정 및 DOM 재사용 구현 - key가 있는 자식을 재배치할 때 기존 DOM 재사용 - key 변경 시 이전 인스턴스 cleanup 및 새로 마운트 - DOM 노드 재배치 로직 추가 (reorderDomNodes) - useEffect 훅 구현 - 의존성 배열 기반 조건부 실행 - 이전 cleanup 함수 실행 후 새 effect 실행 - 렌더링 후 비동기 실행 - 언마운트 및 cleanup 처리 개선 - 언마운트된 컴포넌트의 훅 상태 정리 - key 변경 시 cleanup 함수 실행 - visited 경로 관리로 정확한 cleanup 수행 - Fragment 동적 렌더링 지원 - Fragment의 모든 DOM 노드 재귀적 수집 - Fragment 자식 변경 시 올바른 DOM 구조 유지
…utoCallback) - useState를 사용하여 안정적인 ref 객체를 생성하는 useRef 구현 - 커스텀 equals 함수를 사용한 의존성 비교로 useMemo 구현 - useMemo를 사용하여 useCallback 구현 - deepEquals를 사용한 useDeepMemo 구현 - 최신 상태를 참조하면서도 안정적인 참조를 가진 콜백을 생성하는 useAutoCallback 구현
- useRef를 사용하여 이전 props와 렌더링 결과를 저장하는 memo HOC 구현 - equals 함수로 props 비교하여 불필요한 리렌더링 방지 - deepEquals를 사용하여 props를 깊게 비교하는 deepMemo HOC 구현
- 중복으로 작성된 값제거 - console.log 제거
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.
과제 체크포인트
배포 링크
https://totter15.github.io/front_7th_chapter2-2/
기본과제
Phase 1: VNode와 기초 유틸리티
core/elements.ts:createElement,normalizeNode,createChildPathutils/validators.ts:isEmptyValueutils/equals.ts:shallowEquals,deepEqualsPhase 2: 컨텍스트와 루트 초기화
core/types.ts: VNode/Instance/Context 타입 선언core/context.ts: 루트/훅 컨텍스트와 경로 스택 관리core/setup.ts: 컨테이너 초기화, 컨텍스트 리셋, 루트 렌더 트리거Phase 3: DOM 인터페이스 구축
core/dom.ts: 속성/스타일/이벤트 적용 규칙, DOM 노드 탐색/삽입/제거Phase 4: 렌더 스케줄링
utils/enqueue.ts:enqueue,withEnqueue로 마이크로태스크 큐 구성core/render.ts:render,enqueueRender로 루트 렌더 사이클 구현Phase 5: Reconciliation
core/reconciler.ts: 마운트/업데이트/언마운트, 자식 비교, key/anchor 처리core/dom.ts: Reconciliation에서 사용할 DOM 재배치 보조 함수 확인Phase 6: 기본 Hook 시스템
core/hooks.ts: 훅 상태 저장,useState,useEffect, cleanup/queue 관리core/context.ts: 훅 커서 증가, 방문 경로 기록, 미사용 훅 정리기본 과제 완료 기준:
basic.equals.test.tsx,basic.mini-react.test.tsx전부 통과심화과제
Phase 7: 확장 Hook & HOC
hooks/useRef.ts: ref 객체 유지hooks/useMemo.ts,hooks/useCallback.ts: shallow 비교 기반 메모이제이션hooks/useDeepMemo.ts,hooks/useAutoCallback.ts: deep 비교/자동 콜백 헬퍼hocs/memo.ts,hocs/deepMemo.ts: props 비교 기반 컴포넌트 메모이제이션과제 셀프회고
작업일지
11/17
과제시작!
매번 일단 코드를 먼저 쳤던것 같은데 이번엔 발제자료를 먼저 읽어보고 진행해보려 합니다.
normalizeNode에서 배열은 어떻게 처리하지...?
일단 faltMap으로 평탄화를 해줬긴 합니다.
11/18
과제 요구사항에서 왜 이런 함수가 필요한지에 대한 이해가 없으니 코드를 작성하기가 어려웠습니다. 테스트 코드를 기준으로 잡고 어느정도 작성을 하고 있지만 react에 대한 근본적인 이해가 필요한것 같아서 GPT 선생님한테 물어봤습니다...
createElement는 언제 사용하는가?
JSX를 Virtual DOM 객체로 변환할 때 자동으로 호출되는 함수.
사용되는 타이밍은
첫렌더링시와상태가 변경되었을때.babel은 어떻게 createElement를 사용하는가?
babel은 아래의 플러그인을 파싱시 사용함.
위의 설정을 통해서 JSX가 Virtual Dom 객체로 변경된다
setup함수를 만들면서...
setup은 createRoot사용시 사용됨
createRoot는 main 함수 즉, 애플리케이션 초기화때 사용됨.
vNode의 type이
'div','span' 같은 문자열이면 -> HTML 태그
Function이면 -> 함수 컴포넌트
Class이면-> 클래스 컴포넌트
함수컴포넌트일경우 이걸 호출하면 vnode를 반환함.
함수 컴포넌트
JSX
vnode
이를 render시
11/19
reconciliation이란 뭔가?
react는
setState,useState,props 변화,context 변화등을 감지하면 컴포넌트를 다시 렌더링두개를 비교해서 어떤 부분이 달라졌는지 찾는다.
그 차이점만 실제 DOM에 반영하는 과정이 Reconciliation
reconciliation 규칙
Fiber
Reconciliation은 Fiber 구조로 동작.
-> Fiber은 Reconciliation을 실행하는 엔진
reconcile 함수의 sudo코드
removeInstance)insertInstance)2-1. 새노드가 함수인경우,
2-2. 텍스트 노드일 경우
2-3. Fragment일 경우
-
2-4. HTML 요소일 경우
-
3. 타입이나 키가 다르면 기존 인스턴스를 제거하고 새로 마운트
4. 타입과 키가 같으면 인스턴스를 업데이트
11/20
아하! 모먼트 (A-ha! Moment)
가끔 hook의 순서를 지키라는 오류가 떴는데 이런이유 였구나...!
기술적 성장
이번 과제내용을 이해하기 위해서는 상태변경시 reconcile 과정을 어떻게 진행하는지, hook이 어떻게 동작하는지, 이걸위해 어떤구조로 데이터를 저장하는지, 그리고 이게 어떻게 연결되어 react의 기능을 하는지에 대해 공부해야 했습니다.
context의 구조
RootContext (렌더링 루트 관리)
렌더링의 최상위 정보를 관리
HooksContext (훅 상태 관리)
각 컴포넌트의 훅 상태를 경로 기반으로 격리하여 관리
EffectsContext (이펙트 큐 관리)
렌더링 완료 후 비동기로 실행
hook과 render 관계
reconcile 동작 방식
Instance 구조
Instance는 VNode와 실제 DOM을 연결하는 데이터 구조
kind: 노드 타입 (HOST, TEXT, COMPONENT, FRAGMENT)
dom: 실제 DOM 노드 참조
node: 가상 DOM 노드 (VNode)
children: 자식 인스턴스 배열
key: 리스트 렌더링용 키
path: 컴포넌트의 고유 경로 (hooks 관리용)
useState 동작 방식
useState가 호출될때 cursor(컴포넌트에서 hook의 순서)와 path(컴포넌트의 path)값을 클로저로 저장한다.
hooksState[cursor] = inithook의 배열을 업데이트후render()useEffect 동작 방식
context.effects.queue.push)(reconcile 호출후)
마주친 문제들
eventHandler 중복 저장
여기서 toBe가 3으로 나와서 테스트가 통과가 안됐는데 원인은 addEventlistner가 중복으로 들어가서 였음
updateDomProps실행시 변경되거나 제거된 이벤트 핸들러 제거후 새롭게 추가된 props 추가하게 변경
컴포넌트 삭제로인해 경로가 변경된 경우
context.hooks.state
위의 코드에서 length값이 3->2로 바뀌면 저장되었던 Footer의 상태값이 바뀌면서 '0.c0.c4'에 저장된 Footer의 상태값을 쓰지못하고 '0.c0.c3'에 저장된 값인 0이 상태값으로 나오면서 테스트가 실패
변경후 context.hooks.state
코드 품질
reoncile 함수를 작성하면서 동작 방식을 이해하기 위해서 instance를 이해해야하는데 이걸 이해하려면 다시 reconcile이 어떤건지 이해해야하는 순환구조가 반복되서 reconcile 함수부분은 AI에게 맡겼습니다. 그러다보니 해당부분만 계속 떼우는 방식으로 진행하니 코드가 지저분해진것 같습니다,,, 아직 reconcile을 완전히 이해한건 아니라 리팩토링을 하면서 이해하는 시간을 가져볼까 합니다,,,
학습 효과 분석
사실 프론트엔드 개발자로서 react의 동작구조를 알아야지라는 생각만 가지고 정작 깊게 파보는건 미뤄둔 상태로 있었는데 이번 기회에 로직부분을 다룰수 있어서 좋았습니다. 아마 혼자였다면 여기까지 이해하는데 더 시간이 걸렸을것 같습니다.
이번 과제를 하면서 정말 많은 지식을 접했는데 이걸 제걸로 만들기엔 일주일이란 시간은 확실히 짧은것 같습니다.
과제 피드백
리뷰 받고 싶은 내용
코치님은 보통 학습을 할때 어떤 과정을 거치시나요? (00을 공부해봐야지 -> 일단 개념을 공부해본다/일단 써본다 등)
'00을 공부해봐야지' 라는 생각을 어떤때에 하시게 되나요?
이번 과제는 리액트를 만들어보는거였는데 이후에 학습내용으로 추천하는게 있으실까요?