4월 프리온보딩 프론트엔드 챌린지
1. Render and Commit
리액트가 화면을 렌더링 하는 순서를 살펴보자.
컴포넌트: 요리사. 주방에서 재료로 맛있는 요리를 조립한다.
리액트: 웨이터. 고객의 요청을 접수하고 주문을 가져온다.
- 렌더링 트리거
- 리액트: 손님이 Card 컴포넌트를 커밋해달라고 하신다. 준비해 줘.
- 손님의 주문을 컴포넌트 주방으로 전달
- 컴포넌트 렌더링 (주방에서 주문 준비)
- 컴포넌트: Card 컴포넌트 준비(요리 중)
- 업데이트를 수행해서 화면을 변경하는 것
- DOM에 커밋 (테이블에 주문하기)
- 리액트: 테이블에 Card 컴포넌트를 올려둠
- 변경된 화면을 실제 브라우저에 나타내는 것
2. 렌더링 트리거
리액트에서 렌더링이 발생될 수 있는 경우는 총 2가지.
- It’s the component’s initial render. (컴포넌트의 초기 렌더링)
- The component’s (or one of its ancestors’) state has been updated. (컴포넌트의 상태가 업데이트 되었을 때)
1. 초기 렌더링
앱이 시작될 때 초기 렌더링을 트리거한다. target DOM node로 createRoot를 호출한 다음, 컴포넌트로 render 메서드를 호출하여 수행한다.
main.tsx에는 다음과 같은 코드가 있다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
1. createRoot
브라우저 DOM 노드 안에 React 컴포넌트를 표시하는 루트를 생성하는 메서드
createRoot에 마우스를 올려보면, 다음과 같은 설명이 나온다.
function createRoot(container: Element | DocumentFragment, options?: ReactDOM.RootOptions | undefined): ReactDOM.Root
Replaces ReactDOM.render when the .render method is called and enables Concurrent Mode.
.render 메서드가 호출되고 Concurrent 모드를 활성화할 때 ReactDOM.render를 대체합니다.
@see — https://reactjs.org/docs/concurrent-mode-reference.html#createroot
- 첫 번째 인자: container: Element | DocumentFragment
document.getElementById('root')처럼 Element나 DocumentFragment가 온다.
- 두 번째 인자: options?: ReactDOM.RootOptions | undefined
- Concurrent Mode
ReactDOM.createRoot를 찍어보자
console.log(
ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
);
// ReactDOMRoot {_internalRoot: FiberRootNode}
ReactDOMRoot 인스턴스가 생성되는데 이는, FiberRootNode를 통해 생성되는 인스턴스이다.
DOMTree의 node들은 VirtualDOM에서 Fiber로 나타낸다
Fiber란?
-
리액트 렌더링/업데이트의 가장 작은 단위
-
work라고도 한다 -
효율적인 업데이트를 위해
- work를 중지하고, 필요 시 다시 시작할 수 있어야 한다.
- 다른 종류의 work들에게 우선순위를 부여할 수 있어야 한다.
- 이미 완료된 work를 재사용 할 수 있어야 한다.
- work가 더이상 필요 없게 되면 버릴 수 있어야 한다.
-
Fiber는 key로 구분된다
- array.map() 사용 시 0번째 인덱스에 값을 추가하는 것은 지양한다
- 다른 array들 끼리는 key가 중복되어도 괜찮다
- 불필요한 tag를 추 가하는 것을 지양한다
// react-dom.development.js
var FunctionComponent = 0;
var ClassComponent = 1;
var IndeterminateComponent = 2; // Before we know whether it is function or class
var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
HostRoot에 Root of a host tree 라는 주석이 달려있다.
즉, ReactDOMRoot 인스턴스는 리액트 앱의 가장 최상단 Root이다.
아무튼, createRoot는 VirtualDOM Tree에서 <div id=”root” />를 나타내는 node를 생성하는데 VirtualDOM은 다음 같은 역할을 한다.