React. ch1. 09. 리액트의 리랜더링 (2)
○ 리액트 공식문서
(https://ko.reactjs.org/docs/rendering-elements.html)
○ React element는 불변객체(immuterble)
- element가 한번 만들어지고 ReactDOM.render로 주입 요청 -> 변경 판단 및 반영은 리액트가 알아서 한다.
○ 재조정 (Reconciliation)
(https://ko.reactjs.org/docs/reconciliation.html)
- 비교 알고리즘 (Diffing Algorithm)
두 개의 트리(변경 전, 변경 후)를 비교할 때, React는 두 엘리먼트의 루트(root) 엘리먼트부터 비교합니다. 이후의 동작은 루트 엘리먼트의 타입에 따라 달라집니다.
엘리먼트의 타입이 다른 경우( 변경 전 : 버튼 요소 -> 변경 후 : a tag 요소 )
두 루트 엘리먼트의 타입이 다르면, React는 이전 트리를 버리고 완전히 새로운 트리를 구축합니다. <a>에서 <img>로, <Article>에서 <Comment>로, 혹은 <Button>에서 <div>로 바뀌는 것 모두 트리 전체를 재구축하는 경우입니다.
DOM 엘리먼트의 타입이 같은 경우( 변경 전 : 버튼 요소 -> 변경 후 : 버튼 요소 )
key를 먼저 비교하고, props를 비교해서 변경사항을 반영한다.
같은 타입의 두 React DOM 엘리먼트를 비교할 때, React는 두 엘리먼트의 속성을 확인하여, 동일한 내역은 유지하고 변경된 속성(props)들만 갱신합니다. (props : className, style 등)
<!DOCTYPE html>
<html lang="en">
<body>
<!-- 리액트를 사용하기 위한 CDN -->
<script
crossorigin
src="https://unpkg.com/react@17/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/@babel/standalone/babel.min.js"
></script>
<div id="root1"></div>
<script type="text/babel">
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div> // Date(), toLocaleTimeString() 는 MDN 문서 참조
);
ReactDOM.render(element, document.getElementById("root1"));
}
// It is 오전 9:52:19. 에서
// It is 와 . 은 변경되지 않음(F12 > elements > 깜빡이지 않음)
// 9:52:19 만 변경됨(F12 > elements > 깜빡임)
// 리액트 자체에서 무엇이 바뀌었는지 판단하는 알고리즘이 있다.
// 판단이 어려울 경우 그 부분 전체를 바꾼다. (빠를 속도 지향)
setInterval(tick, 1000);
</script>
</body>
</html>