JSX → React
Virtual DOM
<body>
<!-- <p>Actual DOM</p> -->
<script src="./index.js"></script>
</body>
실제 DOM model 컨트롤
// Actual DOM
var actual_dom = document.createElement('p')
actual_dom.innerHTML = 'Actual DOM'
document.body.appendChild(actual_dom)

가상 DOM model 컨트롤
virtual-hyperscript은 실제 virtual tree를 만들어주는 역할을 한다. vdom은 실제 DOM에 렌더링하고 알고리즘을 통해 붙이는(patch)작업을 한다.
h('요소', 'innerHTML')
React.createElement('a', {href: './', className: 'link'}, '클릭')
먼저 h, createElement를 생성한다.
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
예시
<p> 요소에 텍스트 'virtual dom'를 넣는다.
var tree = h('p', 'virtual dom')
var rootNode = createElement(tree)
document.body.appendChild(rootNode)

요소 안에 여러 요소를 추가 할 때는 []
배열로 전달할 수 있다. 또한 배열의 순서대로 출력이 되기 때문에 마크업의 순서를 설정할 수 있다.
var tree = h('div.foo#some-id', [
'입력해주세요 ',
h('span', 'some text'),
h('input', { type: 'text', value: 'foo' }),
])
var rootNode = createElement(tree)
document.body.appendChild(rootNode)

클래스와 아이디 추가하기
태그 안에 속성을 넣고 싶을 때 {}
를 사용해서 넣는 방법도 있지만 아이디와 클래스를 넣을 때는 요소에 바로 입력해서 넣을 수 있다.
h('div.container', list)
h('div', { className: 'container' }, list)
// 위 둘의 결과 값은 같다.
<div class="container"></div>
h('div#container', list)
h('div', { id: 'container' }, list)
// 위 둘의 결과 값은 같다.
<div id="container"></div>
중간 정리
h
, create-element
를 사용해서 가상 요소를 생성하고 가상 tree를 만들 수 있다.
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
// Virtual DOM
var tree = h('p', 'virtual dom')
var rootNode = createElement(tree)
document.body.appendChild(rootNode)
console.log(typeof h) // function
console.log(typeof createElement) // function
console.log(tree) // VirtualNode (가상노드)
가상 DOM 가상 트리 비교 후, 패치
diff()
를 사용해서 기존의 tree
와 newtree
의 변화를 감지하고 변화된 내용을 변수 patches
에 담는다. 그리고 patch()
는 변화된 내용을 변수 rootNode
에 담아 <body>
에 붙인다.
var patches = diff(tree, newTree)
patch(rootNode, patches)
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
var diff = require('virtual-dom/diff')
var patch = require('Virtual-dom/patch')
var count = 0
function render(n) {
return h('p', 'virtual dom ' + n)
}
function update() {
// 새로운 가상 트리를 생성
var newTree = render(++count) // 1, 2, 3, ...
// 기존 가상 트리, 새로운 가상 트리하고 변경점이 있는지 확인
var patches = diff(tree, newTree)
// 변경사항이 발생하면 rootNode에 패치(붙인다)
patch(rootNode, patches)
}
// Virtual DOM
var tree = render(count)
var rootNode = createElement(tree)
document.body.appendChild(rootNode)
window.setInterval(function () {
update()
}, 1400)

가상 DOM 배열 데이터 순환 처리
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
var diff = require('virtual-dom/diff')
var patch = require('Virtual-dom/patch')
var data = ['vue.js', 'angular', 'react']
function render(data) {
var lists = data.map(function (item, index) {
return h('li', item)
})
return h('ul', lists)
}
// Virtual DOM
var tree = render(data)
var rootNode = createElement(tree)
document.body.appendChild(rootNode)

가상 DOM 제거버튼
var data = ['vue.js', 'angular', 'react']
function render(data) {
var lists = data.map(function (item, index) {
return h('li', [
item,
h(
'button',
{
type: 'button',
onclick: function (e) {
data.splice(index, 1)
console.log(data)
update()
},
},
'delete'
),
])
})
return h('ul', lists)
}
function update() {
var newTree = render(data)
var patches = diff(tree, newTree)
patch(rootNode, patches)
}
// Virtual DOM
var tree = render(data)
var rootNode = createElement(tree)
document.body.appendChild(rootNode)
가상 DOM 추가버튼
버튼을 클릭 했을 때 클릭 할 때마다 1, 2, 3, 4, ... 개씩 추가되는 오류를 방지하기 위해 tree=newTree
구문으로 diff()
가 비교하는 값을 바꿔줌
function update() {
var newTree = render(data)
var patches = diff(tree, newTree)
patch(rootNode, patches)
// tree 변수 값 업데이트
tree = newTree
}
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
var diff = require('virtual-dom/diff')
var patch = require('Virtual-dom/patch')
var data = ['vue.js', 'angular', 'react']
function render(data) {
var lists = data.map(function (item, index) {
return h('li', [
item,
h(
'button',
{
type: 'button',
onclick: function (e) {
data.splice(index, 1)
console.log(data)
update()
},
},
'delete'
),
])
})
var list = h('ul', lists)
var input = h('input.add-content', {
type: 'text',
placeholder: 'Add Favorite Framework',
})
var add_button = h(
'button.add-button',
{
type: 'button',
onclick: function (e) {
var input = document.querySelector('.add-content')
// 모델 데이터 업데이트
data.push(input.value)
// 화면 뷰 업데이트
update()
// 콘솔 변경된 데이터 출력
input.value = ''
},
},
'Add'
)
var container = h('div.container', [input, add_button, list])
return container
}
function update() {
var newTree = render(data)
var patches = diff(tree, newTree)
patch(rootNode, patches)
// tree 변수 값 업데이트
tree = newTree
}
// Virtual DOM
var tree = render(data)
var rootNode = createElement(tree)
document.body.appendChild(rootNode)
JSX와 Virtual DOM
// JSX
const reactElement =
<h1 lang='en' className='headline'>
<strong>React</strong>{' '}
<abbr title='Application Programming Interfaces'>APIs</abbr>
</h1>
ReactDOM.render(reactElement, document.getElementById('root'))
// Virtual DOM
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
var abbr = h('abbr', { title: 'Application Programming Interfaces' }, 'APIs')
var strong = h('strong', 'React')
var head = h('h1. headline', { leng: 'en' }, [strong, abbr])
var rootNode = createElement(head)
document.body.appendChild(rootNode)
JSX
JSX란?
XML과 유사한 JS 문법(구문) 확장이다. 또는 XML 문법을 가진 JS 표현 식으로 말하기도 한다.
JSX가 하는 일
JSX가 하는 일은 React 요소(Element)를 만드는 것이다. React.createElement()로 요소를 생성하고 추가하는 것은 그 과정이 복잡하다 이때, JSX를 사용해서 요소를 생성하면 가독성도 높아지고 손쉽게 요소를 추가할 수 있다.
React 요소는 실제 DOM 요소가 아니라, JavaScript 객체이다.
React 요소를 만드는 2가지 방법
React 요소를 만들 때, JSX를 사용하거나 React.createElement()를 사용해서 만들 수 있다. 하지만 React.createElement()를 사용하는 방법은 복잡하기 때문에 대부분 JSX를 사용하여 작업한다.
const app = (
<div className="app">
<h1>React 앱</h1>
</div>
)
const appHeading = React.createElement(
'h1',
null,
'React.createElement() 메서드'
)
const appElement = React.createElement('div', { class: 'app' }, appHeading)
DOM vs 가상 DOM
ReactDOM 모듈은 가상 DOM을 실제 DOM에 장착(Mount)시켜 렌더링(Rendering)한다.
가상 DOM을 사용하는 이유?
UI는 수시로 변경되는데 변경될 때마다 DOM이 변경되면 업데이트된 요소를 다시 렌더링 하는데 이 과정이 UI의 속도를 느리게 한다. 만약 렌더링 해야하는 요소의 수가 많을 수록 비용은 더 많이 들고 속도는 더 느려진다.
가상 DOM은 실제 DOM에 직접적으로 조작하는 것이 아니라, 이전/이후 상태를 비교하여 변경 사항이 발생할 때 변경된 부분만 실제 DOM에 업데이트(patch) 하므로 UI 속도를 대폭 향상시킬 수 있다.
Babel's Compile
Babel은 JSX를 React.createElement()로 컴파일 한다.

참고
Last updated
Was this helpful?