React에서 key는 어떤 항목을 변경, 추가, 삭제할지 식별하는 것을 도와줍니다.
key는 꼭 지정하는 것이 좋고 data의 id와 같이 고유한 값을 지정해 주는 것이 좋습니다.
이때 전체 파일에서 고유할 필요는 없습니다.
인접한 리스트에서만 key 값은 고유하면 됩니다.
항목의 순서가 바뀔 수 있는 경우에 key값에 Index값을 사용하는 것은 적절치 않습니다.
불필요한 렌더링이 일어날 수 있습니다.
key값을 명시해주지 않으면 React는 기본적으로 index를 key로 사용합니다.
React에서는 인접한 요소들에서 Key 값이 설정되어 있지 않다면 index 값을 default로 사용한다고 하였습니다.
위의 gif에서 input에 있는 값들의 동작은 분명 이상합니다.
list의 뒤에 추가될 때는 이상이 없지만 앞에 추가될때는 동작이 이상해지는 것을 확인하였습니다.
이는 React에서 key 값이 동일한 경우에 동일한 DOM 요소를 보여주기 때문입니다.
a를 입력한 input의 요소는 key값 0에 mapping이 되어있습니다.
a의 앞에 list가 추가가 되면 새로 추가된 list가 index 0을 가지게 됩니다.
그래서 value가 a인 input은 key 값 0인 요소에 나타나 버립니다.
따라서 아래와 같이 key 값을 list에 추가해주면 list의 순서가 변경되더라도 key값이 변경되지 않으므로 우리가 원하는 결과를 가져올 수 있습니다.
아래의 코드는 예시에 사용된 코드 입니다.
import { useState } from 'react';
import { faker } from "@faker-js/faker";
function ListWithoutKey() {
const [people, setPeople] = useState(['a', 'b', 'c'])
const unShiftPeople = () => {
const randomName = faker.name.findName();
setPeople([randomName, ...people]);
};
const pushPeople = () => {
const randomName = faker.name.findName();
setPeople([...people, randomName])
}
return (
<>
<ul>
{people.map((person) => (
<li>{person}<input type="text" /></li>
))}
</ul>
<button onClick={unShiftPeople}>unshift</button>
<button onClick={pushPeople}>push</button>
</>
);
}
function ListWithKey() {
const [people, setPeople] = useState([
{ name: "a", id: 12 },
{ name: "b", id: 123 },
{ name: "c", id: 1234 },
]);
const unShiftPeople = () => {
const name = faker.name.findName();
const id = faker.datatype.uuid();
const newPerson = {name, id}
setPeople([newPerson, ...people]);
};
const pushPeople = () => {
const name = faker.name.findName();
const id = faker.datatype.uuid();
const newPerson = { name, id };
setPeople([...people, newPerson]);
};
return (
<>
<ul>
{people.map((person) => (
<li key={person.id}>
{person.name}
<input type="text" />
</li>
))}
</ul>
<button onClick={unShiftPeople}>unshift</button>
<button onClick={pushPeople}>push</button>
</>
);
}
function App() {
return (
<div className="App">
<ListWithoutKey />
<hr />
<ListWithKey />
</div>
);
}
export default App;
출처: https://ko.reactjs.org/docs/lists-and-keys.html#keys
https://ko.reactjs.org/docs/reconciliation.html#keys
'Frontend > React' 카테고리의 다른 글
React css-in-js (0) | 2022.04.06 |
---|---|
React form 블로그 따라 다루기 (0) | 2022.04.06 |
React input onFocus, onBlur(focus out) 😶🌫️ (0) | 2022.04.02 |
React moment locale 적용하기 🌹 (1) | 2022.04.02 |
React Derived State 🥲 (0) | 2022.04.02 |