List
JavaScript에서 map 메서드를 사용해 새로운 배열을 생성하는 방법은 아래와 같습니다.
1
2
3
4
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
이와 유사하게 React에서는 map 메서드를 이용해 컴포넌트 리스트를 생성합니다.
여러 개의 컴포넌트 렌더링하기
엘리먼트 모음을 만들고 중괄호 {}를 이용하여 JSX에 포함 시킬 수 있습니다.
먼저 map() 함수를 사용하여 numbers 배열을 반복 실행합니다.
각 항목에 대해 <li> 엘리먼트를 반환하고 엘리먼트 배열의 결과를 listItems에 저장합니다.
1
2
3
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => <li>{number}</li>);
listItems 배열을 <ul> 엘리먼트 안에 포함하고 DOM에 렌더링합니다.
1
ReactDOM.render(<ul>{listItems}</ul>, document.getElementById("root"));
기본 리스트 컴포넌트
일반적으로 컴포넌트 안에서 리스트를 렌더링합니다.
이전 예제를 numbers 배열을 받아서 순서 없는 앨리먼트 리스트를 출력하는 컴포넌트로 리팩토링할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById("root")
);
이 때, 코드를 실행하면 리스트의 각 항목에 key를 넣어야 한다는 경고가 표시됩니다.
Key
key는 리스트에서 어떤 아이템을 구분하기 위한 고유한 문자열입니다.
React가 어떤 항목을 변경, 추가, 삭제할 지 식별하는 것을 도와줍니다.
Element에 안정적인 고유성을 부여하기 위해 배열 내부의 Element에 지정해야합니다.
1
2
3
4
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => (
<li key={number.toString()}>{number}</li>
));
key를 선택할 때는 리스트에서 유일하게 해당 항목을 식별할 수 있는 문자열을 사용하는 것이 좋습니다.
key 값은 같은 List에 있는 Elements 사이에서만 고유한 값이면 됩니다.
즉, 해당 key는 오로지 형제 사이에서만 유일하면 되고, 전역에서 유일할 필요는 없다는 것입니다.
1
const todoItems = todos.map((todo) => <li key={todo.id}>{todo.text}</li>);
만약 리스트 항목에 명시적으로 key를 지정하지 않으면 React는 기본값으로 index를 key로 사용합니다.
하지만, index를 사용하면 항목의 순서가 바뀌는 경우 성능이 저하되거나 state 관련 문제가 발생할 수 있습니다.
key로 컴포넌트 추출하기
ListItem 컴포넌트를 추출한 경우, ListItem 안에 있는 li 태그 엘리먼트가 아니라 배열의 ListItem 컴포넌트의 엘리먼트가 key를 가져야합니다.
map() 함수 안에 있는 Elements는 꼭 key가 필요하다는 것을 기억합시다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 잘못된 사용법
function ListItem(props) {
const value = props.value;
return (
// 여기에는 key를 지정할 필요가 없습니다.
<li key={value.toString()}>{value}</li>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) => (
// 여기에 key를 지정해야합니다.
<ListItem value={number} />
));
return <ul>{listItems}</ul>;
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById("root")
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 올바른 사용법
function ListItem(props) {
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) => (
// map 함수 내부의 Element에 key를 지정해야 합니다.
<ListItem key={number.toString()} value={number} />
));
return <ul>{listItems}</ul>;
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById("root")
);