공식 문서 중 React의 내부 구조 및 동작을 추정할 수 있는 부분 위주로 살펴보자
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<h1>Hello, world!</h1>);
const element = <h1>Hello, world</h1>;
브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며(plain object) 쉽게 생성할 수 있습니다. React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트합니다.
여기서 두 가지 정보를 알 수 있다.
또한, React 엘리먼트는 JSX 표현식이 치환된 객체이므로 태그 이름, 어트리뷰트 및 값 등의 정보가 있을 것이라고 유추해 볼 수 있다.
const root = ReactDOM.createRoot( document.getElementById('root') );
const element = <h1>Hello, world</h1>; root.render(element);
여기서도 두 가지 정보를 알 수 있다.
const root = ReactDOM.createRoot( document.getElementById('root') );
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
root.render(element);
}
setInterval(tick, 1000);
React DOM은 업데이트 시 변경된 부분만 native DOM에 반영하도록 되어 있다.
React에서는 형제의 태그 이름이 동일하다면 key 어트리뷰트를 선언하도록 권장한다.
n개의 엘리먼트가 있는 트리를 다른 트리로 변환하는 알고리즘은 최소 O(n^3)으로 알려져 있다.
React는 아래 두 조건을 전제로 시간 복잡도가 O(n)인 휴리스틱 알고리즘을 재조정에 사용한다.
1. 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
2. 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해 줄 수 있다.
즉, 다음과 같은 가정을 통해 O(n)의 휴리스틱을 달성했다.
Ref의 바람직한 사용 사례
셋 모두 React에서 컨트롤 가능한 영역인 태그 이름, 어트리뷰트 등이 아니라 native DOM API 등을 직접 컨트롤해야 하는 경우이다.
반대로 말하자면 React가 제어 가능한 부분은 선언형 API를 통해 조작하라는 것!
이를 권고하는 이유
virtual DOM (VDOM)은 UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 React DOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념입니다. 이 과정을 재조정이라고 합니다.
React 내부에는 native DOM과 동기화하기 위한 가상의 virtual DOM이 있다는 것을 알 수 있다.
“virtual DOM”은 특정 기술이라기보다는 패턴에 가깝기 때문에 사람들마다 의미하는 바가 다릅니다. React의 세계에서 “virtual DOM”이라는 용어는 보통 사용자 인터페이스를 나타내는 객체이기 때문에 React elements와 연관됩니다. 그러나 React는 컴포넌트 트리에 대한 추가 정보를 포함하기 위해 “fibers”라는 내부 객체를 사용합니다. 또한 React에서 “virtual DOM” 구현의 일부로 간주할 수 있습니다.
위 글에 따르면 virtual DOM은 React 내부에 실존하는 어떤 구체적인 인스턴스나 value라기보다는 React가 React 엘리먼트와 native DOM을 동기화하기 위한 패턴의 이름을 의미하며 문맥에 따라 지칭하는 실체가 다르다는 것을 알 수 있다. React 내부를 충분히 파악하지 않은 개발자들은 이 부분을 헷갈리기 쉬운데 React 내부에선 실제로 virtual DOM이라는 이름을 가진 개념이 존재하지 않는다.