React Key 값으로 index를 줘도 될까요?
저는 상황에따라 문제가 생길 것이라고 생각합니다. 오늘은 그 이유에 대해서 이야기해볼게요!
우선 React에서 map 메서드를 이용해서 컴포넌트를 render할 때 key값을 주어야 합니다.
그 이유는 효율적으로 컴포넌트를 render하기 위해서입니다!
key를 주어야 하는 이유
const myArr = ['a', 'b', 'c']
myArr.map((item) => {
return <div>{item}</div>;
})
위의 코드처럼 배열이 존재하고 이것을 map 메서드를 통해서 render한다고 생각 해봅시다.
이렇게 했을 때 리액트는 에러를 발생시킵니다.
이 상태에서 key를 주지 않아도 동작은 합니다.
여기에서 추가적으로 a와 b 사이에 z 라는 글자가 들어오게 되면 어떤식으로 동작을 하게 될까요?
<div>a</div>
<div>b</div> --> <div>z</div>
<div>c</div> --> <div>b</div>
+--> <div>c</div>
이런식으로 굉장히 비효율적으로 바뀝니다.
그렇다면 고유한 key값을 주게 된다면 어떻게 될까요?
<div>a</div>
+<div>z</div>
<div>b</div>
<div>c</div>
이렇게 바로 추가되는 것이 효율적인거 같죠? 고유한 key값을 주어야 변화에 대한 감지가 제대로 이루어져서 효율적으로 작동합니다.
key값으로 고유한 값만 주면 되는거면 map메서드의 두번째 인자인 Index를 줘도 되지 않을까요?
고유한 값을 쓰기 위해서 index를 key 값으로 주고, 이 코드는 영어단어가 나오고 영어단어 뜻을 옆에 input에 적는거라고 가정해봅시다.
function App() {
const [myArr, setMyArr] = useState(['apple', 'banana', 'carrot']);
return (
<div className="App">
{myArr.map((item, index) => {
return (
<div key={index}>
INDEX 값: {index} 영어단어: {item} 뜻:
<input type="text">
</div>);
})}
</div>
);
}
결과가 잘 나오네요! 코드를 좀 더 수정해볼까요?
버튼을 누르면 중간에 'hello'라는 문자가 삽입되도록 작성해보겠습니다.
function App() {
const [myArr, setMyArr] = useState(['apple', 'banana', 'carrot']);
const addChar = () => { // 추가된 부분(z삽입)
setMyArr([...myArr.slice(0,1), 'hello', ...myArr.slice(1,)]);
}
return (
<div className="App">
{myArr.map((item, index) => {
return <div key={index}>INDEX 값: {index} 영어단어: {item}
뜻:
<input type="text"></input>
</div>;
})}
<button onClick={() => {addChar()}}>삽입</button> // 추가된 부분
</div>
);
}
그리고 나서 제가 banana의 뜻을 적다가 z를 삽입하는 버튼을 눌러보겠습니다.
버튼 누르기 전
버튼 누른 후
여러분의 예상과 일치하신가요? 저는 처음에는 바나나라는 한글이 banana가 있는 div와 함께 이동할줄 알았습니다.
배열의 요소가 변경되었고 리액트는 고유한 key값을 이용해서 re-render를 하게됩니다.
하지만 원래 banana의 index(key)값은 1이었는데 현재 배열의 요소가 추가되면서 index(key)가 1인것은 hello라는 단어가 되었습니다.
리액트는 index(key)가 1인 요소에 바나나라는 글자가 써있었으니 re-render할때도 동일한 엘리먼트를 보여주려고 합니다.
그래서 지금과 같은 현상이 일어나게 된 것입니다.
어떤가요? index값을 key값으로 주게 되면 문제점이 생길 것 같지 않으신가요?
그러면 어떤 값을 key값으로 쓰면 좋을까요?
- 요소의 키는 항상 고유해야합니다.
- 안정적이어야 합니다. 요소 재정렬, 시간이 지남에 따라 영향 받지 않아야 됩니다.
- 예측이 가능해야합니다.
이러한 것을 잘 지켜서 사용하시면 좋을 것 같네요! (ex) DB에서 불러온 사용자 정보의 id값 같은경우는 auto_increment도 되고 절대 겹칠리 없을 거 같네요.
* 잘못된 정보가 있다면 댓글로 바로 잡아주시길 바랍니다! 저도 공부중이라 많이 미흡한 점 죄송합니다.
'코딩 > React' 카테고리의 다른 글
Refusing to install package with name "webpack" under a package 오류 해결 (0) | 2021.11.17 |
---|---|
React(리액트) Context API 이해하기!(useContext) (0) | 2020.09.28 |
React 에서 apikey 깃허브에 올리지 않는방법(개인정보 숨기기) (2) | 2020.09.23 |
React로 SPA(Single Page Application)을 만드는 방법 + 예제 (0) | 2020.09.22 |
리액트에서 immer 이용하여 push,slice 사용하기(불변성 유지) (0) | 2020.09.21 |