front_7th_chapter2-2

React 구현을 위한 기초 지식

목차

  1. VNode와 컴포넌트 모델
  2. 렌더 사이클과 루트 관리
  3. 리컨실리에이션과 자식 비교 전략
  4. DOM 속성, 스타일, 이벤트
  5. Hook 컨텍스트와 상태 관리
  6. 스케줄링과 이펙트 실행
  7. 재사용을 위한 유틸리티 패턴

1. VNode와 컴포넌트 모델

예제

// JSX가 어떤 VNode 트리로 바뀌는지 따라가 보기
const vnode = createElement(
  "ul",
  null,
  createElement("li", { key: "a" }, "Todo A"),
  createElement("li", { key: "b" }, "Todo B"),
);
// key가 있는 자식은 경로가 0.ka처럼 key 기반 토큰으로 만들어진다.

2. 렌더 사이클과 루트 관리

예제

// 상태 업데이트가 여러 번 일어나도 render는 한 번만 호출되도록 예약
const render = () => console.log("render once");
const scheduleRender = withEnqueue(render);

scheduleRender();
scheduleRender();
// 콘솔에는 'render once'가 한 번만 출력된다.

3. 리컨실리에이션과 자식 비교 전략

예제

// 이전 자식 배열
const prev = ["A", "B", "C"].map((text) => createElement("li", { key: text }, text));
// 새 자식 배열 - B와 A 위치가 바뀌고 D가 추가됨
const next = ["B", "A", "C", "D"].map((text) => createElement("li", { key: text }, text));
// 키를 기준으로 하면 기존 DOM을 재활용하면서 최소 이동만 발생한다.

4. DOM 속성, 스타일, 이벤트

예제

const oldHandler = () => console.log("old click");
const newHandler = () => console.log("new click");
const button = document.createElement("button");

updateDomProps(button, { onClick: oldHandler, style: { color: "red" } }, {
  onClick: newHandler,
  style: { color: "blue", fontWeight: "bold" },
});
// -> click 리스너는 교체되고, color는 파란색으로 변경, fontWeight 추가, red는 제거됨

5. Hook 컨텍스트와 상태 관리

예제

function Counter() {
  const [count, setCount] = useState(0); // 커서 0
  const ref = useRef(null);             // 커서 1
  useEffect(() => {
    ref.current = count;
  }, [count]);                          // 커서 2
  return createElement("span", null, count);
}
// 훅 순서가 바뀌면 저장된 커서와 상태 배열이 맞지 않아 오류가 난다.

6. 스케줄링과 이펙트 실행

예제

const queue: Array<{ run: () => void }> = [
  { run: () => console.log("effect 1") },
  { run: () => console.log("effect 2") },
];

const flushEffects = withEnqueue(() => {
  while (queue.length) {
    queue.shift()?.run();
  }
});

flushEffects();
flushEffects();
// effect 1, effect 2가 각각 한 번만 실행된다.

7. 재사용을 위한 유틸리티 패턴

예제

// shallowEquals를 직접 실험해 보기
shallowEquals({ a: 1, b: 2 }, { a: 1, b: 2 }); // true
shallowEquals({ a: 1 }, { a: 1, b: 3 });       // false
// memo(Component, shallowEquals)을 구성할 때 어떤 props에서 리렌더가 막히는지 알 수 있다.

결론

MiniReact를 스스로 구현하려면 위 지식이 서로 어떻게 맞물리는지 이해해야 합니다. VNode 트리와 경로 규칙으로 컴포넌트를 식별하고, 렌더 사이클과 리컨실리에이션으로 DOM을 최소한으로 갱신하며, Hook 컨텍스트와 스케줄링을 통해 상태·이펙트를 안정적으로 관리합니다. 이 기반 위에서 equality 유틸리티, HOC, 추가 Hook 같은 확장 기능을 자연스럽게 구축할 수 있습니다.