일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- programmers
- 카드뉴스
- wai-aria
- JavaScript
- 프로그래머스
- 비트연산자
- 알고리즘
- leetcode
- TypeScript
- html&css
- react-query
- 디자인
- 정규표현식
- react
- 제로베이스 프론트엔드 스쿨
- 웹접근성
- Today
- Total
記錄
[React 스터디-5] List, Key 본문

공식 문서 : https://ko.reactjs.org/docs/lists-and-keys.html
* 공식문서 내용을 참고로 작성한 글이기 때문에 위의 공식 링크를 읽는 걸 추천합니다.
List
List 는 목록이라는 뜻으로, 프로그래밍에서는 같은 아이템을 순서대로 모은 것이 리스트에 해당한다. 이를 위해 사용하는 자료구조는 배열(Array)이다. 배열은 자바스크립트의 변수나 객체들을 하나의 변수로 묶어놓은 것이다.
List를 이용해 여러 개의 컴포넌트 렌더링하기
서버에서 내려주는 데이터만큼 렌더링할 수 있도록, 반복해야 하는 개수만큼 return하지 않고 Javascript의 map() 을 이용해 여러 개의 컴포넌트를 렌더링할 수 있다.
//map 사용 X
export default function PreviewCardParent(){
return (
<>
<PreviewCard imgSrc={""} title={""} subtitle={""} author={""} />
....(반복)
</>
)
}
//map 사용 O
export default function PreviewCardParent(){
return (
<>
{cardInfos.map((info)=>(
<PreviewCard imgSrc={"info.imgSrc"} title={"info.title"} subtitle={"info.subtitle"} author={"info.author"} />
))}
</>
)
}
numbers 배열을 받아서 리스트를 출력하는 컴포넌트 예시이다.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<NumberList numbers={numbers} />);
위 코드를 실행하면 다음과 같이 numbers가 li 안에 잘 출력되지만, 콘솔을 확인해 보면 다음과 같은 오류가 뜬다.

이 부분을 해결하기 위해서는 요소에 Key 값을 추가해야 한다.
Key
Key는 리액트에서 아이템들을 구분하기 위한 고유한 문자열로, 리액트가 어떤 항목을 변경, 추가 또는 삭제할 지 식별하는 것을 돕는 역할을 한다. 요소의 안정적인 고유성을 부여하기 위해(=유니크한 개별의 객체) 배열 내부의 엘리먼트에 지정해야 한다.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
//li 에 key 값을 부여하면 더 이상 위의 에러가 발생하지 않는다
Key를 설정할 때는 고유하게 식별할 수 있는 문자열을 사용하는데, 보통 데이터의 ID 값을 활용한다.
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
id 값이 없으면 배열의 index 값을 활용하는 방법도 있지만, 배열이 재배열될 경우 성능이 저하될 수 있으며, 컴포넌트의 state가 의도한 대로 작동하지 않을 수 있어 이 방법은 권장하지 않는다. 리스트 항목에 명시적으로 key를 지정하지 않을 경우 리액트는 기본적으로 index를 key로 사용한다.
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
자식들이 key를 가지고 있다면, 리액트는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인하기 때문에 트리의 변환 작업을 효율적으로 수행할 수 있게 된다. 매번 새로 트리를 그리는 것이 아니라 기존과 비교해 효율적으로 트리를 변경할 수 있게 된다는 것이다.
리렌더링 시 key를 사용하지 않고 데이터를 추가하면 새롭게 추가된 부분 이하 리스트 요소에 전부 영향을 주고, 데이터를 삭제할 시 데이터 추가와 동일하게 변경된 리스트 요소 이하 리스트 요소 모두 영향을 미치기 때문에 비효율적이다.
그러나 key를 사용하면 변경되지 않은 값들은 그대로 두고 변경된 부분(추가, 삭제 등)만 업데이트되기 때문에 렌더링 성능이 향상된다.
key는 형제 사이에서만 고유한 값이면 되고(=같은 List에 있는 Elements 사이에서만 고유한 값이면 된다), 전체 범위에서 고유할 필요가 없으므로 서로 다른 배열에서 동일한 key를 사용할 수 있다.

map() 함수 안에 있는 요소들은 꼭 key값이 필요하다는 부분을 유의하고 사용해야 한다.
Key로 컴포넌트를 추출할 경우, ListItem 안에 있는 li 엘리먼트가 아니라 배열의 <ListItem /> 엘리먼트가 key를 가져야 한다.
function ListItem(props) {
// key 지정 X
return <li>{props.value}</li>;}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// key 지정 O
<ListItem key={number.toString()} value={number} /> );
return (
<ul>
{listItems}
</ul>
);
}
Key는 힌트를 제공하지만 컴포넌트로 전달하지는 않기 때문에 컴포넌트에서 key와 동일한 값이 필요할 경우, 다른 이름의 prop으로 명시적으로 전달해야 한다.
const content = posts.map((post) =>
<Post
key={post.id} id={post.id} title={post.title} />
);
//post.id 는 읽을 수 있지만 post.key는 읽지 못함!
참고자료
https://tecoble.techcourse.co.kr/post/2021-04-25-react-key/
https://yung-developer.tistory.com/107
'FRONTEND STUDY > React' 카테고리의 다른 글
[React 스터디] SPA, Routing (0) | 2023.01.09 |
---|---|
[React 스터디 - 6] 리액트 CSS 적용 방법 (0) | 2022.12.25 |
[React Study - 5] Life cycle, useEffect() (0) | 2022.12.11 |
[React 스터디 - 4] State (0) | 2022.12.04 |
[React Study - 3] Components, Props (0) | 2022.11.28 |