
Fiber는 React가 App 상태의 내부 표현을 유지하는 아키텍처입니다. FiberRootNode와 FiberNode들로 구성된 트리와 같은 구조입니다. 여러 종류의 FiberNode가 있으며 그 중 일부는 DOM 노드를 가지고 있는 HostComponent입니다.
React 런타임은 Fiber 트리를 유지하고 업데이트하며 최소한의 업데이트로 DOM을 동기화 하려고 하고있습니다
HostComponent는 React에서 실제 DOM 요소와 직접적으로 매핑되는 컴포넌트를 의미합니다. 쉽게 말해서
<div><span><p><input><button>// 이건 HostComponent가 아님 (FunctionComponent)
function MyComponent() {
return <div>Hello</div>;
}
// 이것도 HostComponent가 아님 (ClassComponent)
class AnotherComponent extends React.Component {
render() {
return <span>World</span>;
}
}
HostComponent가 중요한 이유는:
stateNode 속성이 실제 DOM 노드를 참조합니다즉, HostComponent는 React의 가상 세계와 브라우저의 실제 DOM을 연결해주는 다리 역할을 한다고 볼 수 있습니다.
1.1 FiberRootNode
FiberRootNode는 React 루트 역할을 하는 특별한 노드로, 전체 앱에 대한 필요한 정보를 보유합니다.
FiberRootNode의 current는 실제 Fiber 트리를 가리키며, 새로운 Fiber 트리가 구성될 때마다 current를 새로운 HostRoot로 다시 가리킵니다.
1.2 FiberNode
FiberNode는 FiberRootNode를 제외한 모든 노드를 의미하며, 중요한 속성은 다음과 같습니다
1. `tag`: FiberNode는 `tag`로 구분되는 여러 하위 타입을 가집니다. 예를 들어, FunctionComponent, HostRoot, ContextConsumer, MemoComponent, SuspenseComponent 등이 있습니다.
2. `stateNode`: 다른 백업 데이터를 가리킵니다. `HostComponent`의 경우 `stateNode`는 실제 백업 DOM 노드를 가리킵니다.
3. `child`, `sibling`, `return`: 이들은 함께 트리와 같은 구조를 형성합니다.
4. `elementType`: 우리가 제공하는 컴포넌트 함수나 내장 HTML 태그입니다.
5. `flags`: Commit 단계에서 적용할 업데이트를 나타냅니다. `subtreeFlags`는 하위 트리에 대한 것입니다.
6. `lanes`: 대기 중인 업데이트의 우선순위를 나타냅니다. `childLanes`는 하위 트리에 대한 것입니다.
7. `memoizedState`: 중요한 데이터를 가리킵니다. FunctionComponent의 경우 이는 훅들을 의미합니다.
React의 초기 마운트 과정:
createRoot()로 React 앱 초기화root.render()가 호출되면performConcurrentWorkOnRoot()가 시작점current: 현재 화면에 표시된 Fiber 트리workInProgress: 새로 만들어지는 Fiber 트리prepareFreshStack()으로 새로운 workInProgress 트리 준비renderRootSync()에서 while 루프로 작업 수행workLoopSync()performUnitOfWork 호출updateHostRoot로 처리mountIndeterminateComponent로 처리updateFunctionComponent로 처리updateHostComponent로 처리updateHostText로 처리<a>텍스트</a>)shouldSetTextContent로 최적화 여부 결정finalizeInitialChildren 단계에서 처리<button>{count}</button>)createTextInstance로 새 텍스트 노드 생성completeWork() 단계에서 실제 DOM 노드 생성createInstance로 실제 DOM 요소 생성appendAllChildren으로 DOM 트리 구성finalizeInitialChildren으로 초기 속성 설정과 이벤트 리스너 등록shouldTrackSideEffects 플래그로 불필요한 작업 방지reconcileChildren()으로 자식 요소들 처리reconcileSingleElement: 단일 엘리먼트 처리reconcileChildrenArray: 배열 처리placeSingleChild: DOM 삽입 필요성 표시mountChildFibers() 사용reconcileChildFibers() 사용React의 Commit 단계 초기 마운트 과정은 다음과 같습니다:
commitMutationEffects: 전체 프로세스를 시작합니다.commitMutationEffectsOnFiber: 각 Fiber 노드별로 처리합니다.recursivelyTraverseMutationEffects: 하위 트리를 먼저 처리합니다.commitReconciliationEffects: 실제 DOM 조작을 수행합니다.parentFiber.subtreeFlags & MutationMask로 하위 트리의 mutation 효과를 확인합니다.captureCommitPhaseError로 처리됩니다.commitPlacement를 호출합니다.insertOrAppendPlacementNodeIntoContainer를 통해:getHostSibling을 통해 결정됩니다:<App/> 컴포넌트가 Placement 플래그를 가집니다.이러한 과정을 통해 React는 준비된 DOM 노드들을 실제 웹 페이지에 반영하게 됩니다.
React의 초기 마운트 전체 과정을 다음과 같이 요약할 수 있습니다:
createRoot()로 시작root.render()performConcurrentWorkOnRoot()에서 시작reconcileChildren()으로 자식 요소 처리mountChildFibers() 사용completeWork()에서 실제 DOM 노드 생성commitMutationEffects 실행commitPlacement로 DOM 노드 삽입