Key 속성에 따른 재사용성
Each child in an array should have a unique "key" prop. Check the render method of Component.
List 형태 등의 데이터를 통해 컴포넌트를 구성하다 보면 위의 경고 메시지를 보신 적이 있을 것입니다.
해당 경고 메시지는 각각의 컴포넌트에 고유 'key'
값을 가져야 하기 때문에 컴포넌트를 확인해달라는 내용으로써, 컴포넌트에 key
속성 값을 고윳값으로 가지도록 수정한다면 해당 경고 메시지를 해결할 수 있습니다.
key
속성에 고유의 값을 부여하면 이 데이터는 어떻게 쓰일까요? 부여받은 key
를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인하는 값으로 사용하고 있다고 합니다.
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
2014
key를 가진 엘리먼트는 새롭게 생성되어 추가되었으며,2015
와2016
의 key를 가진 엘리먼트를 기존에 생성되었던 엘리먼트를 재사용하여 사용되고 있습니다.
React 공식문서에서는 해당 내용을 다음과 같이 설명하고 있습니다.
이 내용을 좀 더 명시적으로 확인하기 위하여 key
속성값이 변경되는 경우와 key
속성값을 변경되지 않는 경우에 대하여 컴포넌트가 mount
, unmount
될 경우 로그가 출력되도록 코드를 작성하였습니다.
버튼 선택 시 key
변경되는 경우
const Item = (props) => {
useEffect(() => {
console.debug("component mount");
return () => {
console.debug("component unmount");
}
}, []);
return <div>전달받은 {props.id}</div>;
};
const App = () => {
const [ id, setId ] = useState(0);
return (
<div className="App">
<Item key={id} id={id}/>
<button onClick={() => setId(Math.random())}>id값 변경</button>
</div>
);
}
버튼 선택 시 key
값이 변경되지 않는 경우
const Item = (props) => {
useEffect(() => {
console.debug("component mount");
return () => {
console.debug("component unmount");
}
}, []);
return <div>전달받은 {props.id}</div>;
};
const App = () => {
const [ id, setId ] = useState(0);
return (
<div className="App">
<Item key={0} id={id}/>
<button onClick={() => setId(Math.random())}>id값 변경</button>
</div>
);
}
key
값이 변경될 경우에는 mount, unmount시
발생하는 로그가 출력되고 있지만, 변경되지 않을 경우에는 해당 로그가 출력되지 않습니다. 따라서 key
값에 따라 컴포넌트가 재사용될 수도 또는 다시 렌더링 될 수도 있다는 걸 확인할 수 있습니다.
결론
key
값에 고유값이 아닌 Math.random()
값과 같이 변화하는 값을 사용하게 된다면 의도치 않은 렌더링이 발생시킬 수 있으며, 이러한 의도치 않은 렌더링은 퍼포먼스 측면에서 영향을 끼칠 것입니다. 따라서 의도치 않은 렌더링을 막기 위해서 key
속성값에 고윳값을 입력하도록 해야 합니다.
참고자료
(React Docs: reconciliation)[https://reactjs.org/docs/reconciliation.html#keys]