220413 웹TIL) 리액트 - key props와 컴포넌트의 차이 - key props편

2022. 4. 14. 01:24코딩/TIL

 

아직 React의 key-props 그리고 컴포넌트들이 헷갈린다. 이참에 이 둘의 개념들에 대해 한 번 정리해보자. 

 

Warning: Each child in an array or iterator should have a unique "key" prop ...

리액트를 개발하다 보면 자주 나오는 Error.. 이전 포스팅에서도 이 에러에 대해 다뤘다. 

 

왜 React의 Element에 key prop이 필요하고, key prop을 사용하면서 주의해야 할 점? 

- 재조정 (Reconcilation) 

key prop을 이해하기에 앞서 React가 화면을 어떻게 업데이트 하는지 알 필요가 있다. React는 새로운 엘리먼트를 그리기 위해 비교 알고리즘 (Diffing Algorithm)을 이용해서 효율성을 최대화한다. 

 

ex) 엘리먼트의 타입이 다른 경우 

// before
<div> 
	<Counter /> 
</div> 

//after
<span> 
	 <Counter /> 
</span>

이 경우는 아예 DOM을 새로 그리는 경우로 이전의 컴포넌트 인스턴스(Counter)은 모두 파괴되고 새로운 인스턴스가 생성된다. 이때 기존의 Counter 컴포넌트에서는 componentWillUnmount()가 실행될 것이며 새로운 인스턴스에는 componentWillMount()와 componentDidMount()가 새롭게 실행될 것이다. 

 

ex) 엘리먼트의 타입이 같은 경우 

// before 
<div style={{color:'red', fontWeight:'bold'}}/> 


//after
<div style={{color:'green', fontWeight:'bold'}}/>

이 경우는 두 엘리먼트 타입이 동일하기 때문에 두 엘리먼트의 속성만 비교하며 동일한 내역은 유지하고 변경된 속성값만 갱신한다. 위에서는 fontWeight는 수정하지 않고 color값만 새롭게 수정한다. 이 경우는 기존의 엘리먼트는 기존의 state 값을 유지하며 새로운 속성을 반영하기 위해 컴포넌트의 props를 갱신한다. 이때 컴포넌트의 해당 인스턴스의 componentWillReceiveProps()와 componentWillUpdate()를 호출한다. > 이 두 라이프사이클은 React 16.8부터 사용x 

 

 

자식에 대한 재귀적 처리 

// before 
<ul> 
	<li>first</li> 
    <li>second</li>
</ul> 

//after
<ul> 
	<li>first</li>
    <li>second</li>
    <li>third</li> 
</ul>

key prop이 넘겨지지 않은 선택. 

위와 같이 마지막에 새로운 엘리먼트를 추가 하는 것은 크게 성능 문제를 유발하지 않는다.

React는 모든 자식 노드를 순회하면서 차이점이 있으면 변경을 생성하는데 위 같은 경우는 첫번째, 두번째 엘리먼트가 똑같고 마지막에 <li>third</li>를 추가하면 되기 때문에 모든 자식 노드를 새로 그릴 필요 없이 변경된 사항만 새롭게 그리면 된다. 

 

// before 
<ul> 
	<li>Hello</li>
    <li>Seoul</li> 
</ul> 

// after
<ul>
	<li>Gwangju</li> 
    <li>Hello</li> 
    <li>Seoul</li> 
</ul>

새로운 엘리먼트가 마지막이 아니라 첫번째로 들어간다  

이 경우에는 React는 모든 요소가 제자리에 위치하지 않았다고 생각하고 종속 트리는 유지하지만 모든 자식 엘리먼트를 새로 그린다. 이 경우에는 의도치 않게 성능이슈 유발 가능 

 

>> key prop을 넣어 엘리먼트를 다시 생성 

// before 
<ul> 
	<li key="2015">Hello</li> 
    <li key="2016">Seoul</li> 
</ul> 

// after 
<ul> 
	<li key="2014">Gwangju</li>
    <li key="2015">Hello</li>
    <li key="2016">Seoul</li>
</ul>

key props를 넣어주면 React는 2014 key를 가진 엘리먼트가 새로 추가되고 2015, 2016 key는 그저 엘리먼트 이동만 하면 된다. 

 

참고 

https://awesomezero.com/development/react-key/