React 내부 동작원리를 알아보자(1) - 리액트 패키지의 구성요소, 용어 정리

방구석 코딩쟁이·2024년 1월 24일
0

이 시리즈는 "가장 쉬운 웹개발 with Boaz" 님의 [React 까보기 시리즈] 를 기반으로 만들어졌습니다.

React의 주요 패키지

React core

Component를 정의
다른 패키지에 의존성이 없으므로 다양한 플랫폼(브라우저, 모바일 등)에서 사용 가능합니다.

Renderer

react-dom, react-native-renderer 등 호스트 렌더링 환경에 의존합니다.
호스트 렌더링 환경과 react를 연결합니다.
(예시) 웹에서는 DOM 조작)
reconciler와 legacy-events 패키지 의존성을 가지고 있습니다.

event(legacy-events)

내부적으로 SyntheticEvent 라는 이름으로 개발된 이벤트 시스템 입니다.
기존 웹에서의 이벤트를 래핑하여 추가적인 기능을 수행할 수 있게 해줍니다.

Scheduler

React는 Task를 비동기로 실행합니다. 이 Task를 실행하는 타이밍을 알고 있는 패키지입니다.

Reconciler

Fiber Architecture에서 VDOM(가상 돔)의 재조정을 담당합니다.
컴포넌트를 호출하는 곳입니다.

용어 정리

렌더링

컴포넌트를 호출하여 react element를 리턴받고, VDOM에 적용(재조정)하는 과정을 의미합니다.

전체 과정을 간략하게 설명하면 아래와 같습니다.

  1. 컴포넌트를 호출하여 react element를 리턴합니다.
  2. VDOM 재조정 작업을 실행합니다 (여기까지가 렌더링 작업)
  3. renderer가 컴포넌트 정보를 DOM에 삽입합니다 (이것을 mount라고 부릅니다)
  4. 브라우저가 DOM을 paint 합니다.

react element

컴포넌트를 호출할 때 리턴하는 것입니다
(JSX는 Babel을 통해 React.createElement()를 호출합니다.)
컴포넌트 정보(결국 DOM에 삽입될 내용)를 담은 객체이며 컴포넌트의 정보는 아래와 같습니다.

  • type, key, props, ref

fiber

VDOM의 노드 객체입니다 (아키텍처의 명칭과 동일합니다)
react element의 내용이 DOM에 반영되기 위해 VDOM에 추가되어야 하는데 이를 위해 확장된 객체입니다.
(컴포넌트의 상태, life cycle, hook이 관리됩니다.)

Fiber 코드는 아래와 같습니다.

function FiberNode(tag, pendingProps, key){
  // Instance
  this.tag = tag; // fiber의 종류를 나타냄
  this.key = key;
  this.type = null; // 추후에 React element의 type을 저장
  this.stateNode = null; // 호스트 컴포넌트에 대응되는 HTML element를 저장

  // Fiber
  this.return = null; // 부모 fiber
  this.child = null; // 자식 fiber
  this.sibling = null; // 형제 fiber
  this.index = 0; // 형제들 사이에서의 자신의 위치

  this.pendingProps = pendingProps; // workInProgress는 아직 작업이 끝난 상태가 아니므로 props를 pending으로 관리
  this.memoizedProps = null; // Render phase가 끝나면 pendingProps는 memoizedProps로 관리
  this.updateQueue = null; // 컴포넌트 종류에 따라 element의 변경점 또는 라이프사이클을 저장
  this.memoizedState = null; // 함수형 컴포넌트는 훅을 통해 상태를 관리하므로 hook 리스트가 저장된다.

  // Effects
  this.effectTag = NoEffect; // fiber가 가지고 있는 side effect를 기록
  this.nextEffect = null; // side effect list 
  this.firstEffect = null; // side effect list
  this.lastEffect = null; // side effect list 

  this.expirationTime = NoWork; // 컴포넌트 업데이트 발생 시간을 기록
  this.childExpirationTime = NoWork; // 서브 트리에서 업데이트가 발생할 경우 기록

  this.alternate = null; // 반대편 fiber를 참조
}
profile
풀스택으로 나아가기

0개의 댓글