티스토리 뷰
아래와 같은 jsx코드가 있다고 했을 때
<h1 id="name" className="username" >{user.name}</h1>
<ul>
<li>{board[0]}</li>
<li>{board[1]}</li>
</ul>
화면에는 아래처럼 그려진다.
<h1>윤두준</h1>
<ul>
<li>잘생겼다.</li>
<li>귀엽다.</li>
</ul>
그런데 데이터에 수정이 생기면, 예를 들어 "윤두준"을 "양요섭"으로 바꾸면 화면을 다시 그려야 화면에 보여지는게 바뀐다.
화면을 다시 그리기 위해 h1, ul 모두 다시 그릴 필요없이 바뀐 h1의 텍스트("윤두준")부분만 바뀌면 가장 좋을 텐데
리액트는 React Element로 되어있기 때문에 최소한 Element 단위, 여기서는 h1 Element를 다시 그린다.
JSX는 아래와 같은 형태의 자바스크립트 코드로 컴파일되는데
React.createElement(component, props, ...children)
그럼 위 jsx의 h1과 ul은 아래처럼 컴파일된다.
React.createElement('h1', {id: 'name', className: 'username'}, `${user.name}`)
React.createElement('ul', null,
React.createElement('li', null, `${borad[0]}`),
React.createElement('li', null, `${borad[1]}`)
)
위 코드는 함수형태로 바꿀 수 있는데
변경되는 데이터를 props로 받고 데이터가 변경되면 리액트가 해당 함수를 다시 호출 (화면을 다시 그리려고)
function h1(props)
이 h1이라는 함수의 return 값이 {user.name}
ul은 return 값은
<li>{board[0]}</li>
<li>{board[1]}</li>
이제 h1이라는 함수를 DOM의 이벤트 리스너로 등록하면 되는데 DOM의 이벤트 리스너는 브라우저가 가지고 있다.
그러니 이 이벤트 리스너는 DOM이 아니라 React에 등록하는데 따로 등록할 필요 없이 h1을 사용하는 쪽에서 h1을 작성하면 등록이 된 것.
<h1>{user.name}</h1>
컴파일 할 때 import된 거든 function 선언된거든에서 h1을 찾음.
h1에서 user.name이라는 변수를 사용한다는 걸 리액트가 등록해놓고 자바스크립트로 컴파일함.
user.name이 바뀌면 리액트가 h1 함수를 호출.
그럼 h1 부분이 다시 그려짐.
전체를 다시 그리기엔 DOM은 너무 무거우니 DOM에는 변경된 것들 return 한거 가지고 그릴때만 접근.
그럼 DOM에 접근하기 전에 h1같은 함수 속에 있는 태그들은 어디에 있나 -> Virtual DOM
Virtual DOM은 DOM과 같은 구조를 메모리에 담고 있다. (함수니까 실행컨텍스트에 올리기 가능)
데이터가 변경되면 Virtual DOM이 바뀌는 것
<h1 id="name" className="username" >{user.name}</h1>
<ul>
<li>{board[0]}</li>
<li>{board[1]}</li>
</ul>
만약 위에서 board[0] 변수 값이 바뀌었다고 헀을 때 ul이라는 함수를 찾아서 다시 호출함
querySelector, innterText 등을 이용해서 값을 바꾼다면 그건 DOM에 접근한 것 -> DOM Tree는 무겁다. (그나마 getElementById로 접근하면 빠름. 유니크한 값이니까 브라우저가 빨리 찾으려고 map에다 올려놓음. 캐시해놓음)
DOM에서 remove, append하기는 힘드니까 Virtual DOM에서만 바뀜
Virtual DOM은 실행컨텍스트에 올라가있고 board[0]을 참조하고 있음
board[0]이 바뀜 -> 이벤트리스너가 타짐 -> ul함수를 부름. 리턴값은 이 때 string임 -> string값을 Virtual DOM에 주면 Virtual DOM의 board[0] 부분이 바뀜 -> 화면을 다시 그림
Virtual DOM이 필요한 이유는
만약 li가 20개라고 치면 board을 수정하면 li 20개가 다 다시 그려져야함
근데 board에서 실제 값이 바뀐건 board[0]뿐이라고 하면 첫번째 li만 다시 그리면 됨
첫번째 li만 다시 그리려고 했더니 li가 너무 많음 -> DOM 탐색 안하려고 key값을 설정 -> key를 주면 array에서 map으로 바뀜
id나 key안주면 리액트가 컴파일하면서 알아서 줌 -> Virtual DOM은 내부에서 DOM Tree가 아니라 map임 -> 탐색에 힘을 안뺌(빠름)
이 Virtual DOM 덕분에 리액트가 처음 나왔을때 다른 프레임워크보다 빨랐다고 한다. (지금은 밀렸지만ㅠ)
참고 자료
🔗 [시니어코딩] React 이론 3강 - 실무 코드로 훑어보는 React의 작동원리
🔗 [reactjs.org] JSX 없이 사용하는 React
'개발공부 > 🟦 React.js' 카테고리의 다른 글
[React] 리액트 생명주기 (React Lifecycle) (0) | 2023.03.21 |
---|---|
[React] 리액트를 사용하는 이유와 그와 관련한 핵심 기능 (0) | 2023.02.20 |
[React] React 앱 빌드와 배포 (0) | 2023.02.16 |
[React] Server Side Rendering (0) | 2023.02.16 |
[React] React 테스팅 (0) | 2023.02.15 |
프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그