[ 요약 ]
array.map()
: 동일한 컴포넌트 구조에 서로 다른 데이터 렌더링array.filter()
: 원하는 조건에 해당하는 항목만 필터링key
를 사용해서 리스트 항목을 순서대로 유지- 위치가 변경되더라도 생명주기 내내 해당 항목을 key로 식별 가능
- 형제 항목 간에 항목을 고유하게 식별
index
로 key값을 대신할 경우 배열의 순서가 바뀌었을 때 렌더링 순서 변경 위험key={Math.random()}
과 같이 즉석에서 key 생성 ❌
[ 학습 내용 ]
- JavaScript의
map()
을 사용하여 배열을 컴포넌트로 렌더링하는 방법- JavaScript의
filter()
를 사용하여 특정 컴포넌트만 렌더링하는 방법- React에서 Key가 필요한 때와 이유
리스트 항목의 유일한 차이점 : 데이터
서로 다른 데이터를 사용하여 동일한 컴포넌트의 여러 인스턴스를 표시해야하는 경우
해당 데이터를 Javascript 객체와 배열에 저장하고 배열 메서드를 사용하여 해당 객체에서 컴포넌트 리스트 렌더링 가능
- 데이터를 배열로 이동
people
의 요소를 새로운 JSX 노드 배열인listItems
에 매핑<ul>
로 래핑된 컴포넌트의listItems
반환
const people = [
'Creola Katherine Johnson: mathematician',
'Mario José Molina-Pasquel Henríquez: chemist',
'Mohammad Abdus Salam: physicist',
'Percy Lavon Julian: chemist',
'Subrahmanyan Chandrasekhar: astrophysicist'
];
export default function List() {
const listItems = people.map(person =>
<li>{person}</li>
);
return <ul>{listItems}</ul>;
}
JavaScript의 filter()
메서드를 사용하여 해당하는 사람만 반환
array.filter()
: boolean을 반환하는 함수를 인수로 받아 true가 반환된 항목만 있는 새로운 배열 반환
person.profession === 'chemist'
로 필터링해서 “chemist”로만 구성된 새로운 배열 chemists 생성- 이제 chemists를 매핑
- 마지막으로 컴포넌트에서 listItems를 반환
import { people } from './data.js';
import { getImageUrl } from './utils.js';
export default function List() {
const chemists = people.filter(person =>
person.profession === 'chemist'
);
const listItems = chemists.map(person =>
<li>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}:</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
return <ul>{listItems}</ul>;
}
화살표 함수는 암시적으로 =>
바로 뒤에 식을 반환하기 때문에 return
문 필요 ❌
const listItems = chemists.map(person =>
<li>...</li> // 암시적 반환!
);
하지만 =>
뒤에 {
중괄호가 오는 경우 return
을 명시적으로 작성해야함
const listItems = chemists.map(person => { // 중괄호
return <li>...</li>;
});
=> {
를 표현하는 화살표 함수 : “block body”를 가지고 있다고 표현
return문을 작성하지 않으면 아무것도 반환되지 않음
key
를 사용해서 리스트 항목을 순서대로 유지하기각 배열 항목에 다른 항목 중에서 고유하게 식별할 수 있는 문자열 또는 숫자를 key
로 지정해야함
<li key={person.id}>...</li>
Key는 각 컴포넌트가 어떤 배열 항목에 해당하는지
React에 알려주어 나중에 맵핑
배열 항목이 이동할 경우(index가 바뀌는 경우) 중요
key를 잘 선택하면 React가 정확히 무슨 일이 일어났는지 추론하고 DOM 트리에 올바르게 업데이트
즉석에서 key를 생성하는 대신 데이터 안에 key를 포함해야함
import { people } from './data.js';
import { getImageUrl } from './utils.js';
export default function List() {
const listItems = people.map(person =>
<li key={person.id}>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
return <ul>{listItems}</ul>;
}
map()
호출 내부의 JSX 엘리먼트에는 항상 key가 필요
여러 개의 DOM 노드를 렌더링해야 하는 경우 → <div>
또는 <Fragment>
를 사용하여 key 전달
Fragment는 DOM에서 사라지므로 <h1>
, <p>
, <h1>
, <p>
등의 평평한 리스트 생성
import { Fragment } from 'react';
// ...
const listItems = people.map(person =>
<Fragment key={person.id}>
<h1>{person.name}</h1>
<p>{person.bio}</p>
</Fragment>
);
key
를 가져오는 곳데이터 소스마다 다른 key 소스 제공
폴더의 파일 이름과 배열의 JSX key는 비슷한 용도로 사용
-> 형제 항목 간에 항목을 고유하게 식별
잘 선택된 key는 배열 내 위치보다 더 많은 정보를 제공
-> 위치가 변경되더라도 생명주기 내내 해당 항목을 key로 식별 가능
배열에서 항목의 index를 key로 사용 유의 🚨
key를 전혀 지정하지 않으면 React는 인덱스를 사용하긴 함
But, 배열의 순서가 바뀌면 시간이 지남에 따라 항목을 렌더링하는 순서 변경
key={Math.random()}
과 같이 즉석에서 key 생성 ❌
→ 렌더링 간에 key가 일치하지 않아 모든 컴포넌트와 DOM 재생성
→ 속도가 느려질
뿐만 아니라 리스트 항목 내부의 모든 사용자 입력 손실
컴포넌트가 key를 prop으로 받지 않음 → React 자체에서 힌트로만 사용