// 함수형 컴포넌트에서 <div></div> 태그안에 숫자를 넣는 예제이다 const keyError = ():JSX.Element => { const numbers= [1, 2, 3] return ( <>numbers.map((number) => <div>number</div>)</> ) }
Warning: Each child in a list should have a unique "key" prop.
React를 사용할때 map 함수를 사용하여 배열로 요소를 추가하게 될시에 위와 같은 경고문구를 볼 수 있다
공식홈페이지에서 알아본 결과 react는 요소들을 트리로 변환하기 위해 O()의 복잡성을 가지고 있어서 O(n)의 복잡성으로 바꾸기 위한 힌트로 사용된다고 한다
예를들어 1000개 요소를 key 없이 재구성한다면 10억건의 비교를 하게되는 리소스를 아낄 수 있는 것이다
- key 값을 index로 사용했을때 나타나는 문제
/** - 정상적인 렌더링 A -> B로 변경과 같이 마지막에 추가하게 되는 경우 첫번째와 두번째에 1 과 2가 일치하므로 3번째에 추가만 하면 되는 상황이라 제대로 된 렌더링이 발생하게 된다 */ // A <ul> <li>1</li> <li>2</li> </ul> // B <ul> <li>1</li> <li>2</li> <li>3</li> </ul>
/** - 비효율적인 렌더링 A -> B로 변경과 같이 첫번째에 추가하는 경우 React는 트리 구성중 A의 "<li>1</li> => <li>3</li>" "<li>2</li> => <li>1</li>" " undefined => <li>2</li>" 와 같이 모든 트리를 재구성하게 되어 비효율적인 렌더링을 하게된다 */ // A <ul> <li>1</li> <li>2</li> </ul> // B <ul> <li>3</li> <li>1</li> <li>2</li> </ul>
/** - 자식노드 전체 재구성에대한 비효율적인 레더링 해결책 => key key props 사용하여 기존에 있던 엘리먼트들은 "이동"만 시키고 새로운 key를 가진 엘리먼트만 "추가"하면 된다는걸 알려주면 된다 */ // A <ul> <li key="1">1</li> <li key="2">2</li> </ul> // B <ul> <li key="3">3</li> <li key="1">1</li> <li key="2">2</li> </ul> /** 예외사항 key props를 배열의 인덱스로 사용하는 경우 'A' => 0 'B' => 1 'C' => 2 해당 요소마다 각각의 인덱스가 0,1,2각각 엘리먼트의 키 값으로 들어가는 경우 요소의 첫번째에 'D'가 추가되었다고 가정해보자 'D' => 0 'A' => 1 'B' => 2 'C' => 3 그럼 위와 같이 각 요소마다 인덱스가 변경되고 기존 A가 가지고 있던 key = 0 을 D가 가지게 되고 A가 1의 key 값을 가지게 됨으로써 장애가 발생하게 된다 */ const keyError = (props):JSX.Element => { const {numbers}= props; // ['A', 'B', 'C']; return ( <>numbers.map((number,index) => <div key={index}>number</div>)</> ) }