TIL: React에서 key 값으로 index를 넣으면 안되는 이유

Snoop So·2023년 5월 15일
0
import styles from './Tab.module.css';
import classNames from 'classnames/bind';
import { Button } from '@components/index';

export const Tab = ({ buttonTexts, activeIndex }) => {
	const cx = classNames.bind(styles);

	const tabClassNames = `${cx('tab')}`;

	const isActive = (index, activeIndex) => activeIndex === index;
	const getButtonClassNames = (index, activeIndex) =>
		isActive(index, activeIndex) ? cx('active') : '';

	return (
		<div className={tabClassNames}>
			{buttonTexts.map((text, i) => (
				<Button
                  	key={??}
					className={getButtonClassNames(i, activeIndex)}
					text="BUTTON"
					width="160px"
					size="m"
					icon="plus"
					type="ghost"
				></Button>
			))}
		</div>
	);
};

Button 컴포넌트가 중복 생성되고 있는 상황이므로 React가 개별 버튼을 식별하도록 돕기 위해 key 값이 필요하다. 그렇다면 key 값은 중복되지 않은 고유한 값을 사용해야 한다.
언뜻 보면 Array.map 메소드의 두번째 프로퍼티인 i(index)를 key로 사용하면 편리할 것 같다. 그렇지만 이것은 불필요한 리렌더링을 유발할 수 있다.

이런 상황을 생각해보자.

  1. 사용자가 배열의 첫 번째 요소를 삭제하려고 한다.
  2. 배열의 요소들이 삭제된 후, 인덱스를 key로 사용하면 key 값이 업데이트된다.
  3. 이로 인해 React 가 기존 요소와 새 요소를 정확히 비교하지 못하고 불필요한 리렌더링이 발생한다.
// 삭제 전
<Button key="0">첫번째</Button>
<Button key="1">두번째</Button>

//삭제 후
<Button key="0">두번째</Button>
// '첫번째'라는 텍스트를 가진 버튼이 삭제되었지만 React는 key 값으로 엘리먼트를 구분하므로 변경사항을 정확히 확인하지 못할 수 있다.
// 리액트가 인식하기로는 key 값이 0번인 버튼의 텍스트가 변경된 것으로 인지하게 됨

0개의 댓글