> For the complete documentation index, see [llms.txt](https://shhn0509.gitbook.io/react/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shhn0509.gitbook.io/react/react-study/start/jsx-react.md).

# JSX → React

## Virtual DOM

```markup
<body>
  <!-- <p>Actual DOM</p> -->
  <script src="./index.js"></script>
</body>
```

### 실제 DOM model 컨트롤

```javascript
// Actual DOM
var actual_dom = document.createElement('p')
actual_dom.innerHTML = 'Actual DOM'
document.body.appendChild(actual_dom)
```

![실제 텍스트가 렌더링 되고 index.js파일도 잘 불러와 진 것을 확인 할 수 있다. ](/files/-MSb_QKxWrOC9t0SbkAd)

### 가상 DOM model 컨트롤

[virtual-hyperscript](https://github.com/Matt-Esch/virtual-dom/blob/master/virtual-hyperscript/README.md)은 실제 virtual tree를 만들어주는 역할을 한다. vdom은 실제 DOM에 렌더링하고 알고리즘을 통해 붙이는(patch)작업을 한다.&#x20;

```javascript
h('요소', 'innerHTML')
React.createElement('a', {href: './', className: 'link'}, '클릭')
```

{% hint style="info" %}
React.createElement()

```javascript
React.createElement('a', {href: './', className: 'link'}, '클릭')
```

{% endhint %}

먼저 h, createElement를 생성한다.&#x20;

```javascript
var h = require('virtual-dom/h')
var createElement = require('virtual-dom/create-element')
```

#### 예시&#x20;

\<p> 요소에 텍스트 'virtual dom'를 넣는다.  &#x20;

```javascript
var tree = h('p', 'virtual dom')
var rootNode = createElement(tree)
document.body.appendChild(rootNode)
```

![실제 렌더링 되는 결과 ](/files/-MSdSCwLokDyYo8ugP9N)

요소 안에 여러 요소를 추가 할 때는 `[]`배열로 전달할 수 있다. 또한 배열의 순서대로 출력이 되기 때문에 마크업의 순서를 설정할 수 있다.&#x20;

```javascript
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)
```

![실제 렌더링 되는 결과 ](/files/-MSdRu2lKTy1SbYAAbs5)

**클래스와 아이디 추가하기**

&#x20;태그 안에 속성을 넣고 싶을 때 `{}`를 사용해서 넣는 방법도 있지만 아이디와 클래스를 넣을 때는 요소에 바로 입력해서 넣을 수 있다.&#x20;

```javascript
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>
```

### &#x20;중간 정리&#x20;

`h`, `create-element`를 사용해서 가상 요소를 생성하고 가상 tree를 만들 수 있다.&#x20;

```javascript
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>`에 붙인다. &#x20;

```javascript
var patches = diff(tree, newTree)
patch(rootNode, patches)
```

```javascript
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)
```

![위의 코드에서 각 변수가 가리키는 것을 이미지로 확인 ](/files/-MSdX2T81DOCHKpufOxp)

### 가상 DOM 배열 데이터 순환 처리

```javascript
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)
```

![실제 렌더링 되는 결과 ](/files/-MSdYg8aVPdur2LEHybZ)

### 가상 DOM 제거버튼

```javascript
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()`가 비교하는 값을 바꿔줌&#x20;

```javascript
function update() {
  var newTree = render(data)
  var patches = diff(tree, newTree)
  patch(rootNode, patches)
  // tree 변수 값 업데이트
  tree = newTree
}
```

```javascript
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&#x20;

```javascript
// 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&#x20;

### JSX란?&#x20;

XML과 유사한 JS 문법(구문) 확장이다. 또는 XML 문법을 가진 JS 표현 식으로 말하기도 한다.&#x20;

### JSX가 하는 일&#x20;

JSX가 하는 일은 React 요소(Element)를 만드는 것이다.  [React.createElement()](https://ko.reactjs.org/docs/react-api.html#createelement)로 요소를 생성하고 추가하는 것은 그 과정이 복잡하다 이때, JSX를 사용해서 요소를 생성하면 가독성도 높아지고 손쉽게 요소를 추가할 수 있다.&#x20;

React 요소는 실제 DOM 요소가 아니라, JavaScript 객체이다.&#x20;

### React 요소를 만드는 2가지 방법

React 요소를 만들 때, JSX를 사용하거나 [React.createElement()](https://ko.reactjs.org/docs/react-api.html#createelement)를 사용해서 만들 수 있다. 하지만 [React.createElement()](https://ko.reactjs.org/docs/react-api.html#createelement)를 사용하는 방법은 복잡하기 때문에 대부분 JSX를 사용하여 작업한다.&#x20;

```javascript
const app = (
  <div className="app">
    <h1>React 앱</h1>
  </div>
)
```

```javascript
const appHeading = React.createElement(
  'h1',
  null,
  'React.createElement() 메서드'
)

const appElement = React.createElement('div', { class: 'app' }, appHeading)
```

## DOM vs 가상 DOM

ReactDOM 모듈은 가상 DOM을 실제 DOM에 장착(Mount)시켜 렌더링(Rendering)한다.&#x20;

### 가상 DOM을 사용하는 이유?

UI는 수시로 변경되는데 변경될 때마다 DOM이 변경되면 업데이트된 요소를 다시 렌더링 하는데 이 과정이 UI의 속도를 느리게 한다. 만약 렌더링 해야하는 요소의 수가 많을 수록 비용은 더 많이 들고 속도는 더 느려진다.&#x20;

가상 DOM은 실제 DOM에 직접적으로 조작하는 것이 아니라, 이전/이후 상태를 비교하여 변경 사항이 발생할 때 변경된 부분만 실제 DOM에 업데이트(patch) 하므로 UI 속도를 대폭 향상시킬 수 있다. &#x20;

## Babel's Compile

Babel은 JSX를 React.createElement()로 컴파일 한다. &#x20;

![Babel를 사용해서 React.createElement()로 컴파일 한다. ](/files/-MSe-nV3Bs6UAgdbreEM)

## &#x20;참고&#x20;

* [npm budo ](https://www.npmjs.com/package/budo)
* [virtual-dom](https://github.com/Matt-Esch/virtual-dom)
* [vtree](https://github.com/Matt-Esch/virtual-dom/tree/master/vtree)&#x20;


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://shhn0509.gitbook.io/react/react-study/start/jsx-react.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
