리액트의 동작원리
함수(컴포넌트) → 객체(VDOM) → DOM
1. 함수(컴포넌트) → 객체(VDOM)
- 리액트처럼 컴포넌트를 사용하기 위해서 반환된 JSX 를 가상 돔 JS 로 바꾸어보는 것부터 시작하자!
JSX를 JS로 트랜스파일링?
트랜스파일러: 바벨
const App = () => {
return (
<div>
<h1>hello</h1>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
import { jsx as _jsx } from "react/jsx-runtime";
const App = () => {
return _jsx("div", {
children: _jsx("h1", {
children: "hello"
})
});
}
ReactDOM.render(_jsx(App, {}), document.getElementById("root"));
그러면 react/jsx-runtime 내부구현이 궁금한데요..
- react 레포를 뒤적여서 ReactJSXElement 부분 구현이 가장 코어한 로직이 있는 곳이라고 판단.
- 너무 길어서 일단 GPT의 힘을 빌려 이해하려고 해봤습니다.
잠깐! React.createElement 는 뭐지?
JSX를 사용해 생성된 요소는 일반적으로 React.createElement() 호출로 변환되며, 이 과정에서 해당 요소를 나타내는 React Element라는 객체가 생성됩니다.
const App = () => {
return React.createElement(
"div",
null,
React.createElement("h1", null, "Hello")
);
}
JSX 를 대신하여 리액트 엘리먼트를 생성할 수 있는 문법이라고 한다. 그렇다면 복잡한 JSX 를 파싱하여 다시 내부에서 createElement 를 호출하는 것보다는, 이 함수를 바로 작성하는 것이 구현 난이도가 낮을 것 같다. 시간이 되면 파싱까지 하기! (현재 진행 중)
createElement(type, props, ...children)
- type : 태그 이름 문자열 or React 컴포넌트
- props : React DOM의 속성
- children : React DOM의 하위 React DOM들의 배열
createElement 의 내부구현?
export function createElement(type, config, children) {
// valid한 element인지 체크하는 로직 생략
let propName;
const props = {};
// config가 결국 prop들을 말하는 듯. 순회하며 props 객체에 등록해준다.
for (propName in config) {
props[propName] = config[propName];
}
// 이게 왜있나 했더니, 자식들이 형제 관계로 여러 개 있을 수 있으니 그걸 체크하는듯.
// 2를 뺀건 type이랑 config 개수 뺀거!
const childrenLength = arguments.length - 2;
// 1) 자식이 하나면 그냥 바로 props 객체에 children 키값으로 등록해준다.
if (childrenLength === 1) {
props.children = children;
}
// 2) 자식이 여러개면...
else if (childrenLength > 1) {
// 자식 길이만큼 배열을 하나 만들어준다.
const childArray = Array(childrenLength);
// 받은 자식들을 만든 배열에 다 집어넣는다.
for (let i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
// 완성된 배열을 props 객체에 children 키값으로 등록해준다.
props.children = childArray;
}
잠깐! arguments 는 변수에 없는데 어디서 나온거지?
(→ 근데 최근 ES6 이후에는 나머지 매개변수가 생기면서 …rest 로 쓰는게 좋다고 한다.)
- arguments는 JavaScript의 모든 함수에서 기본으로 제공되는 특별한 객체
- 모든 인수를 순서대로 나열한 것! 함수 내부라면 어디서든지 참조 가능.
- 유사 배열 객체
2. 객체(VDOM) → DOM
ReactDOM.render 로 진입점을 html 에다가 붙여주고 있다! 그럼 봐야겠지?
- 라고 생각해서 찾았는데 나오지 않았다.
다만, React 18부터는 createRoot와 root.render가 새로운 표준이므로, render 메서드는 ReactDOM.createRoot로 이동되었습니다.
- 정말 코드가 복잡했지만, 간단하게 정리하면 아래와 같다.
- document.createElement(containerTagName) 으로 실제 DOM 만들기 함수 (createContainer)
- createContainer 를 활용하여 루트 DOM 만들기
- 그렇다면 더이상 containerTagName 에 컴포넌트(함수)가 들어오지 않을 때까지 재귀로 들어갔다가, string 인 태그 이름이 나오면 document.createElement 해주는 식으로 구현하면 되지 않을까?
실제 DOM으로 변환하기 위한 Document의 메서드들
document.createDocumentFragment()
- 빈 DocumentFragment 객체 반환.
- DocumentFragment 란?
- Document 의 가벼운 버전.
- 내부의 트리를 변경해도 아무 영향도 주지 않고, 리플로우 방지
- Document 란?
- 브라우저가 불러온 웹 페이지.
- DOM트리의 진입점 역할
document.createTextNode()
- 텍스트 노드 반환.
document.createElement(tagName)
- Element 반환.
'프로젝트 > 소프티어 부트캠프' 카테고리의 다른 글
[1주차] 펀딩 프로그래스 업데이트를 위한 실시간 데이터 동기화 기술 (0) | 2025.01.06 |
---|