시간에 쫓기듯 리액트를 공부하던 중 제대로 이해하지 못하고 넘어간 부분이 많다는 생각이 들었다. key
와 관련한 오류는, 그냥 이유는 모르겠고 고유한 값을 넣으라니까 넣어서 해결했다. 또 이유는 기억 안나지만 (아마 이건 수업때 배웠던 것 같은데) index
는 쓰면 안된다. 그냥 그렇게 배웠다. 공식문서에도 그렇게 쓰여있다.
컴포넌트 변경시점이 언제인지 제대로 알지도 못하지만, state
를 바꾸고 props
을 바꾸니까 화면단이 잘 바꼈다. 그래서 그냥 진행했다. 공식문서에 써져있는 코드를 공부하며 상태를 바꿔보니까 그냥 되더라.
이런식으로 진행하다보니 나는 코드만 쓸줄 알고 이게 어느 시점에 렌더링 되고 어떤 계기로 렌더링 되는지, 또 key
는 왜 중요한지 전혀 알지 못하고 있다는 생각이 들었다.
HTML
을 파싱하여 DOM
노드로 이루어진 트리를 생성한다.css
파일과, inline
스타일을 파싱하고 DOM
트리에 이걸 붙인다.attach
라는 노드들이 가진 메서드를 통해 스타일 정보를 계산해 객체 형태로 반환한다.브라우저 렌더링은 위와 같은 4가지 단계를 거쳐 진행되는데, 이러한 방식은 다음과 같은 문제가 있다.
DOM
에 새로운 요소가 삽입되게 되면, 위외 같은 렌더링 단계를 모두 거쳐서 모든 NODE를 다시 렌더링한다.DOM
요소를 30번 바꾼다면, 최대 30번의 리렌더링이 일어난다.DOM
에 브라우저에 그려야 하는 모든 정보가 담겨져 있기 때문에, DOM
을 조작하는 작업이 상대적으로 무겁다.const element = () => {
return (
<a key="key1" style={{ background: 'red' }} href="http://google.com">
Click Here
</a>
);
};
// 이런 jsx 코드가 있다.
console.log(element);
{ ("a",
{
key: 'key1',
ref: null,
style: {
background: 'red'
},
href: "http://google.com",
children: "Click Here",
// 만약 이 노드가, 다른 노드를 가지고 있다면
// 여기서
// [ { "p",
{ ...
}]
// 로 자식 노드가 연결되어 있음을 확인할 수 있다.
...
}
// 콘솔로 찍어보면 이런 모양의 객체가 나오게 된다.
element
객체가 하위 노드를 가지게 된다면, children
에 하위노드의 정보가 출력된다.props.children
이 어떻게 쓰이는지도 알 수 있다.전체 UI를 객체형태로 이루어진 추상적인 정보들을 virtual DOM에 먼저 리렌더링 한다.
diff 알고리즘을 통해, virtual DOM과 현재 내용(실제 DOM)을 비교한다.
(이를 재조정이라고 한다.)
React DOM에 렌더링해야 하는 부분의 정보를 전달한다.
virtual DOM은 diff
알고리즘을 통해 realdom 과 virtual dom을 비교하게 되는데,
리액트 공식문서에 따르면 diff
알고리즘의 기준은 같다.
이러한 부분을 기반에 두고, diff 알고리즘이 진행되는 걸 확인해 보면,
상태가 변경되면, 리액트는 해당 컴포넌트를 dirty
라고 표시한다.
dirty
로 표시된 컴포넌트와 실제 돔을 level by level
로 비교하고 변경점에 대해 다시 렌더한다.
또한, toast 문서를 보면 dff 알고리즘은 다음과 같을때 다른 방식으로 비교한다.
render()
를 호출하고, 컴포넌트의 이전 엘리먼트 트리와 다음 엘리먼트 트리에 대해 diff 알고리즘을 재귀적으로 적용한다.이를 통해 보면, 우리는 컴포넌트를 만들어야 하는 이유를 알 수 있다.
위의 알고리즘 기준을 보면, 같은 위치의 같은 컴포넌트라면 비교는 끝나고 자식요소를 탐색해서 계속해서 비교하지 않을 수 있기 때문이다.
div
로 비교한다면, 다른 부분까지 비교를 계속해서 하게된다.또한 key
에 고유한 값을 적어야 하는 이유를 알 수 있다.
key
를 통해 해당 노드의 재조정이 필요한지 알 수 있기 때문이다.key
에 고유한 값을 적어 두어야만, virtual DOM은 해당 노드를 구분하고 바뀐점이 있는지 확인할 수 있다.key
에 index
를 적으면 안되는 이유도 알 수 있다.key
에 index
를 넣으면 불필요한, 잘못된 재조정을 통해 re-render를 유발할 수 있다.diff
알고리즘을 통해 재귀적으로 자식들까지 계속해서 비교한다.React fiber는 다음과 같은 기능을 제공한다.