# React misunderstanding issues (Part 1)
Study report : https://ithelp.ithome.com.tw/users/20129300/ironman/5892
### Prerequisites
JavaScript
- Closure
- Arrow Function -> Function Component
- Mutable vs. Immutable
- Shallow copy vs. Deep copy
- Functional programming design pattern
---
### React misunderstanding
#### 1. Virtual DOM and DOM (Real DOM)
**Virtual DOM was copy from Real DOM ?**
- React abstract layer (React API)
- the critical optimizing concept : less DOM operation
- init render -> VD -> RD -> update -> create a new VD -> diff update fields -> update RD to match the new VD version
*single flow : Virtual DOM -> Real DOM*

#### 2. React Element & JSX
**React Element is JS object, not HTML element**
- each VD element = React element, the minimal unit of React abstract layer
- can not be modified after creating, we need every element version to ensure the difference
- Even with React.createElement(), why do we need JSX
```javascript
// React.createElement()
const reactElement = React.createElement(
'div',
{ id: 'wrapper', className: 'foo' },
React.createElement(
'ul',
{ id: 'list-01' },
React.createElement('li', { className: 'list-item' }, 'item 1'),
React.createElement('li', { className: 'list-item' }, 'item 2'),
React.createElement('li', { className: 'list-item' }, 'item 3'),
),
React.createElement(
'button',
{ id: 'button1' },
'I am a button'
)
);
// JSX
const reactElementWithJSX = (
<div id="wrapper" className="foo">
<ul id="list-01">
<li className="list-item">item 1</li>
<li className="list-item">item 2</li>
<li className="list-item">item 3</li>
</ul>
<button id="button1">I am a button</button>
</div>
);
```
:::warning
JSX still invoked React.createElement().
We should imagine JSX = value, rather HTML string or Real DOM element.
JSX (React element) -> Babel -> Real HTML DOM
:::
- why does each component require a wrapper or fragment
:::warning
A JSX block = invoke React.createElement() one time, return one React element.
Tree node structure -> one root node (common parent node)
:::
#### 3. Root container
- why do we always create only one root
- why not use "document.body" as root
- React 18 API
#### 4. How updating work
Reconciler、Renderer
| Reconciler | Renderer |
| -------- | -------- |
| React abstract layer | browser |
| create VD、diff fields | transform VD to RD |
| re-render -> component -> diff -> transfer to Renderer | react-dom (Web application)
- React using Object.is() to determine re-render. (!! important)
- We should focus on establish React element(VD) efficiently and reuse non-change React element, rather on DOM operation.
- related topic : React Fiber
#### 5. Batch update
We know setState is async, but...
React would execute all event handlers first, and then trigger a single re-render batching all of those updates together.
:::warning
state is a snapshot
https://beta.reactjs.org/learn/state-as-a-snapshot
:::
```javascript
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
function handleClick() {
console.log(1)
increment(); // add to update queue
increment(); // add to update queue
increment(); // add to update queue and just re-render one time with this result
console.log(5)
}
// how the log working?
```
- Mixed setState
```javascript
const handleClick = () => {
setCount(1);
setName('Foo');
setName('Bar');
setCount(2);
setCount(3);
setCount(pre=>pre+5)
};
// how the flow working?
```
- setState(n=>n+1)
:::warning
An updater function (e.g. n => n + 1) gets added to the queue.
Any other value (e.g. number 5) adds “replace with 5” to the queue, ignoring what’s already queued.
*** updater functions must be pure and only return the result.
Strict mode - running updater function twice (無視第二次的結果,協助 debug side effect)
:::
- if you do not want batch update
React 18 flushSync()
:::danger
React 17 : Only works on sync event, excludes:
1. setTimeout()
2. Promise.then()
3. DOM event callback
React 18 supports all
:::
---
Ref
About btach update
https://overreacted.io/react-as-a-ui-runtime/#batching
https://beta.reactjs.org/learn/queueing-a-series-of-state-updates