JS/React

React - Each child in a list should have a unique "key" prop.

shin96bc 2024. 3. 9. 18:17

발생하는 이유

해당 에러가 발생하는 이유는 jsx에서 map을 이용해서 태그를 생성 하는 경우와 같이 형제관계에서 같은 태그가 여러개 존재할 때 발생하는 Warning 입니다.

 

해결방법

해결방법은 아래와 같이 map 안쪽에서 반복되는 태그중 가장 상위 태그에 고유한 key값을 전달하면 됩니다.

 

여기서 보통 map 함수의 두번째 인자값으로 들어오는 index를 key값으로 많이 사용하는데, 사실 React에서는 index를 key값으로 사용하는 것을 지양하고 있습니다. index 이외에 고유한 값을 사용하는게 좋습니다.

const App = () => {
	const list = [
		{id: 1, name: 'A'}, 
		{id: 2, name: 'B'}, 
		{id: 3, name: 'C'}
	];
		
	return (
		<div>
			{
				list.map((item, index) => {
					// index값을 사용하는 것은 지양하자
					return (
						// 가장 최상위 태그에 key prop을 전달해줍니다.
						<div key={item.id}>
							<p>{item.name}</p>
						</div>
					);
				})
			}
		</div>
	);
}

 

React 내부적으로 사용하는 key란 무엇인가?

key는 React가 어떤 항목을 변경, 추가, 삭제 할 때 element를 식별할 수 있도록 하는 고유한값입니다.

 

key는 element에 안정적인 고유성을 부여하기 위해서 element에 직접 지정합니다.

 

key값으로 사용하는데 가장 적합한 값은 배열의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는게 좋습니다.

 

만약 같은 key값이 부여되면 key값이 충돌해서 사이드 이펙트(의도하지 않은 결과)가 생길 수 있습니다.

 

주의할점은 map 함수의 두번째 인자값으로 주어지는 index값(0부터1씩 증가하는 값)을 key값으로 사용하게 될 경우, 배열의 값이 추가, 삭제, 변경되는 경우에 고유성을 잃어버리기 때문에 index값을 사용하는 것은 지양하도록 합니다.

 

key값을 전달해도 Warning이 발생하는 경우

컴포넌트를 나누면서 작업을 하다보면 key값을 전달했는데 Warning이 발생하는 경우가 있습니다.

// 컨테이너 컴포넌트
const Container = (props) => {
	return (
		<div>
			{props.children}
		</div>
	);
};

export default Container;
// 컴포넌트

// 잘못된 예시
const  Item = (props) => {
	const {id, name} = props;	

	// 바로 이렇게 컴포넌트 내부에서 최상위 태그에 key값을 전달하게되면 React는 key값을 인식하지 못하기 때문에 계속 Warning이 발생합니다.
	// 그렇기 때문에 Item 컴포넌트 자체에 key값을 전달해야합니다.
	return (
		<div key={id}>
			<p>{name}</p>
		</div>
	);
};

// 올바른 예시
const  Item = (props) => {
	const {id, name} = props;	

	// 이렇게 컴포넌트 내부에서는 key값을 전달할 필요가 없습니다.
	return ( 
		<div>
			<p>{name}</p>
		</div>
	);
};

export default Item;
const App = () => {
	const list = [
		{id: 1, name: 'A'}, 
		{id: 2, name: 'B'}, 
		{id: 3, name: 'C'}
	];
		
	return (
		<Container>
			{
				list.map((item) => {
					// key값은 여기서 Item 컴포넌트 자체에 전달하면 됩니다.
					return (
						<Item key={item.id} id={item.id} name={item.name} />
					);
				})
			}
		</Container>
	);
}

 

함께 발생할 수 있는 Warning

해당 Warning은 React 내부에서 사용중인 prop의 이름 'key'를 컴포넌트 안에서 사용하려고할 때 발생합니다.

// 잘못된 예시X
const  Item = (props) => {
	const {key, id, name} = props;	

	return (
		<div key={key}>
			<p>{name}</p>
		</div>
	);
};

export default Item;