이전 포스팅 중 그 빠른 재조정의 핵심 이론을 잠깐 정리하고 가면,
- 서로 다른 type의 element는 완전히 다른 트리를 생성할 것이라고 예상한다. React는 이런 경우에 둘을 비교하지 않고, 이전의 트리를 버린 뒤 완전히 새로 만든다.
- List는 key 속성을 이용해서 비교한다. key값은 안정적이고, 예측 가능하며, 유일해야한다.
Type(태그명)이 달라지면 컴포넌트는 완전히 버리고,
Key 속성을 이용해 List를 비교함으로써 탐색 속도를 비정상적으로 빠르게 성장시켰다고한다.
Key는 DOM에서 존재하지 않는 속성이다.
React가 사용하는 가상의 속성이라고 생각하자.
무려 element.getAttribute("key") 해도 안나온다
React는 Key를 확인하여 이전과 같은 Key라면, DOM 인스턴스를 새로 생성하지 않는다.
그렇지만 반대로, Key값이 달라지면 DOM 인스턴스를 새로 생성한다.
이전까지의 개념과 확실히 다른 내용이다.
React는 같은 위치에 오는 type(태그명)이 바뀌지 않는 한, 마운트 된 상태를 유지하고 속성과 내부 값만 바꿔왔다.
하지만 마운트를 해제하고 싶다면, Key를 바꿈으로써 인스턴스를 초기화할 수 있다.
인스턴스가 초기화되면 내부 state의 완전 초기화와 빈 deps의 useEffect를 초기화하는 등의 효과를 볼 수 있다.
화면상 구조는 같지만, 내부 상태 초기화를 자주 해야되는 경우에 쓰인다.
구조는 변함이 없는데, 반복적으로 데이터가 수정되는 구조를 하나 만들어보겠다.
ListContainer에 상품들이 나열되어있고, 선택된 상품의 정보를 보여주는 ItemSpec이다.
상품 리스트와, 세부 정보를 보여주는 컴포넌트
컴포넌트의 위치가 그대로니 props 데이터를 바꿔도 내부 상태가 유지되는 모습이다..
개수와 옵션을 ItemSpec컴포넌트에서 너무 당연하게도 state로 다루고 있고, props가 변경되었으나 "바뀐 부분만 바꾼다"는 React의 특성때문에 내부 state값들이 초기화되지 않는다.
이는 UX적으로 좋지 못하다. 상품이 바뀌면 기존 상태값들이 기본값으로 초기화되어야한다.
그렇다고 바꿀때마다 일일히 모든 상태에 대해 setState를 다뤄야하는가?
이럴때 key값을 이용할 수 있다. 이전과 같은 key값이 아니라면, 인스턴스를 새로 생성할것이다.
<ItemSpec key={selectedItem} selectedItem={list[selectedItem]}/>
다른 상품을 클릭했을 때, 인스턴스를 초기화하는 모습!
사실 위처럼 key를 써보기보단, 배열에 담긴 데이터를 가지고 요소를 반복생성할때 가장 바깥쪽 태그에 유일한 key값을 넣기만 하는 것이 익숙할 것이다.
배열 요소를 렌더링할때도 위와 같은 논리가 적용된다.
여러가지 요소들이 있고, 요소의 추가&삭제 등에 의해 순서가 바뀌어도 key값이 유지된다면, React는 DOM요소를 새로 만들지 않는다.
Key를 유일한 값으로 줘야 하는 이유도, 같은 key를 가진 요소가 들어온다면, 사라져야하는 요소가 사라지지 않고 남아있는 모습을 보게 될 수도 있다.
글을 다 써가는 시점에서 다른 글들의 참조를 돌아보다가 알게 되었는데,
React의 베타 버전 공식 문서에는 훌륭한 설명들이 많이 있었다.
여태까지 블로깅 된 내용들이 훨씬 풍부하고, 보기좋게 도식화되어 올라와있다.
기본 공식문서를 전부 읽은 사람이라면, 반드시 위 beta문서를 읽어보길 권한다.
React팀은 저 문서가 완료된다면 기존 공식문서를 대체할 것이라 한다.