You will often want to display multiple similar components from a collection of data. You can use the JavaScript array methods to manipulate an array of data. On this page, you’ll use filter()
and map()
with React to filter and transform your array of data into an array of components.
데이터 모음에서 유사한 컴포넌트를 여러 개 표시하고 싶을 때가 많습니다. JavaScript 배열 메서드를 사용해 데이터 배열을 조작할 수 있습니다. 이 페이지에서는 React에서 filter()
와 map()
을 사용해 데이터 배열을 필터링하고 컴포넌트 배열로 변환하겠습니다.
You will learn학습 내용
- How to render components from an array using JavaScript’s
map()
- How to render only specific components using JavaScript’s
filter()
- When and why to use React keys
- JavaScript의
map()
을 사용하여 배열에서 컴포넌트를 렌더링하는 방법 - JavaScript의
filter()
를 사용해 특정 컴포넌트만 렌더링하는 방법 - React에서 key를 사용하는 경우와 그 이유
Rendering data from arrays 배열에서 데이터 렌더링하기
Say that you have a list of content. 다음과 같은 콘텐츠 목록이 있다고 가정해 보겠습니다.
<ul>
<li>Creola Katherine Johnson: mathematician</li>
<li>Mario José Molina-Pasquel Henríquez: chemist</li>
<li>Mohammad Abdus Salam: physicist</li>
<li>Percy Lavon Julian: chemist</li>
<li>Subrahmanyan Chandrasekhar: astrophysicist</li>
</ul>
The only difference among those list items is their contents, their data. You will often need to show several instances of the same component using different data when building interfaces: from lists of comments to galleries of profile images. In these situations, you can store that data in JavaScript objects and arrays and use methods like map()
and filter()
to render lists of components from them.
이러한 목록 항목의 유일한 차이점은 콘텐츠, 즉,데이터입니다. 댓글 목록에서 프로필 이미지 갤러리에 이르기까지 인터페이스를 구축할 때 서로 다른 데이터를 사용하여 동일한 컴포넌트의 여러 인스턴스를 표시해야 하는 경우가 종종 있습니다. 이러한 상황에서는 해당 데이터를 JavaScript 객체와 배열에 저장하고 map()
및 filter()
와 같은 메서드를 사용하여 컴포넌트 목록을 렌더링할 수 있습니다.
Here’s a short example of how to generate a list of items from an array: 다음은 배열에서 항목 목록을 생성하는 방법에 대한 간단한 예시입니다:
- Move the data into an array:
데이터를 배열로 이동합니다:
const people = [
'Creola Katherine Johnson: mathematician',
'Mario José Molina-Pasquel Henríquez: chemist',
'Mohammad Abdus Salam: physicist',
'Percy Lavon Julian: chemist',
'Subrahmanyan Chandrasekhar: astrophysicist'
];
- Map the
people
members into a new array of JSX nodes,listItems
:people
멤버를 새로운 JSX 노드 배열인listItems
에 매핑합니다:
const listItems = people.map(person => <li>{person}</li>);
- Return
listItems
from your component wrapped in a<ul>
: 컴포넌트에서<ul>
로 감싼listItems
를 반환합니다:
return <ul>{listItems}</ul>;
Here is the result: 결과는 다음과 같습니다:
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>; }
Notice the sandbox above displays a console error: 위의 샌드박스에 콘솔 오류가 표시되는 것을 확인할 수 있습니다:
You’ll learn how to fix this error later on this page. Before we get to that, let’s add some structure to your data. 이 오류를 수정하는 방법은 이 페이지의 뒷부분에서 알아보겠습니다. 그 전에 데이터에 몇 가지 구조를 추가해 보겠습니다.
Filtering arrays of items항목 배열 필터링하기
This data can be structured even more. 이 데이터는 훨씬 더 구조화할 수 있습니다.
const people = [{
id: 0,
name: 'Creola Katherine Johnson',
profession: 'mathematician',
}, {
id: 1,
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
}, {
id: 2,
name: 'Mohammad Abdus Salam',
profession: 'physicist',
}, {
id: 3,
name: 'Percy Lavon Julian',
profession: 'chemist',
}, {
id: 4,
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
}];
Let’s say you want a way to only show people whose profession is 'chemist'
. You can use JavaScript’s filter()
method to return just those people. This method takes an array of items, passes them through a “test” (a function that returns true
or false
), and returns a new array of only those items that passed the test (returned true
).
profession이 'chemist'
인 사람만 표시하는 방법을 원한다고 가정해 봅시다. JavaScript의 filter() 메서드를 사용하여 해당 사람들만 반환할 수 있습니다. 이 메서드는 항목 배열을 받아 “테스트”(true
또는 false
를 반환하는 함수)를 통과한 후, 테스트를 통과한 항목만 포함된 새 배열을 반환합니다(true
반환).
You only want the items where profession
is 'chemist'
. The “test” function for this looks like (person) => person.profession === 'chemist'
. Here’s how to put it together:
profession
이 'chemist'
인 항목만 원합니다. 이를 위한 “test” 함수는 (person) => person.profession === 'chemist'
와 같습니다. 이를 조합하는 방법은 다음과 같습니다:
- Create a new array of just “chemist” people,
chemists
, by callingfilter()
on thepeople
filtering byperson.profession === 'chemist'
:
people
에서person.profession === 'chemist'
조건으로filter()
를 호출하여, “chemist”만 있는 새로운 배열인chemists
를 생성합니다:
const chemists = people.filter(person =>
person.profession === 'chemist'
);
- Now map over
chemists
:
이제chemists
위에 매핑합니다:
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>
);
- Lastly, return the
listItems
from your component:
마지막으로 컴포넌트에서listItems
를 반환합니다:
return <ul>{listItems}</ul>;
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>; }
Keeping list items in order with key
key
로 목록의 항목 순서 유지하기
Notice that all the sandboxes above show an error in the console: 위의 모든 예제 샌드박스에서 콘솔에 오류가 표시되는 것에 주목해 봅시다:
You need to give each array item a key
— a string or a number that uniquely identifies it among other items in that array:
각 배열 항목에는 해당 배열의 항목들 사이에서 고유하게 식별할 수 있는 문자열 또는 숫자인 key
를 부여해야 합니다:
<li key={person.id}>...</li>
Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen key
helps React infer what exactly has happened, and make the correct updates to the DOM tree.
key
는 각 컴포넌트가 어떤 배열 항목에 해당하는지 React에 알려주어 나중에 매칭할 수 있도록 합니다. 이는 배열 항목이 (정렬 등으로 인해) 이동하거나, 삽입되거나, 삭제될 수 있는 경우 중요해집니다. 잘 만들어진 key
는 React가 정확히 무슨 일이 일어났는지 추론하고 DOM 트리를 올바르게 업데이트하는 데 도움이 됩니다.
Rather than generating keys on the fly, you should include them in your data: 즉석에서 key를 생성하는 대신 데이터에 포함시켜야 합니다:
export const people = [{ id: 0, // Used in JSX as a key name: 'Creola Katherine Johnson', profession: 'mathematician', accomplishment: 'spaceflight calculations', imageId: 'MK3eW3A' }, { id: 1, // Used in JSX as a key name: 'Mario José Molina-Pasquel Henríquez', profession: 'chemist', accomplishment: 'discovery of Arctic ozone hole', imageId: 'mynHUSa' }, { id: 2, // Used in JSX as a key name: 'Mohammad Abdus Salam', profession: 'physicist', accomplishment: 'electromagnetism theory', imageId: 'bE7W1ji' }, { id: 3, // Used in JSX as a key name: 'Percy Lavon Julian', profession: 'chemist', accomplishment: 'pioneering cortisone drugs, steroids and birth control pills', imageId: 'IOjWm71' }, { id: 4, // Used in JSX as a key name: 'Subrahmanyan Chandrasekhar', profession: 'astrophysicist', accomplishment: 'white dwarf star mass calculations', imageId: 'lrWQx8l' }];
Deep Dive | 심층 탐구
What do you do when each item needs to render not one, but several DOM nodes? 각 항목이 하나가 아니라 여러 개의 DOM 노드를 렌더링해야 할 때는 어떻게 해야 할까요?
The short <>...</>
Fragment syntax won’t let you pass a key, so you need to either group them into a single <div>
, or use the slightly longer and more explicit <Fragment>
syntax:
짧은 <>...</>
Fragment 구문으로는 key를 전달할 수 없으므로 단일 <div>
로 그룹화하거나, 약간 더 길고 더 명시적인 <Fragment>
구문을 사용해야 합니다:
import { Fragment } from 'react';
// ...
const listItems = people.map(person =>
<Fragment key={person.id}>
<h1>{person.name}</h1>
<p>{person.bio}</p>
</Fragment>
);
Fragments disappear from the DOM, so this will produce a flat list of <h1>
, <p>
, <h1>
, <p>
, and so on.
Fragment는 DOM에서 사라지므로, 이렇게 하면 <h1>
, <p>
, <h1>
, <p>
등의 1차원 목록이 생성됩니다.
Where to get your key
key
를 얻을 수 있는 곳
Different sources of data provide different sources of keys: 데이터 소스에 따라 서로 다른 key 소스를 제공합니다:
- Data from a database: If your data is coming from a database, you can use the database keys/IDs, which are unique by nature.
- Locally generated data: If your data is generated and persisted locally (e.g. notes in a note-taking app), use an incrementing counter,
crypto.randomUUID()
or a package likeuuid
when creating items.
- 데이터베이스의 데이터: 데이터베이스에서 데이터를 가져오는 경우, 고유한 데이터베이스 key/ID를 사용할 수 있습니다.
- 로컬에서 생성된 데이터: 데이터가 로컬에서 생성되고 유지되는 경우(예: 메모 작성 앱의 메모), 항목을 만들 때 증분 카운터,
crypto.randomUUID()
또는uuid
와 같은 패키지를 사용하세요.
Rules of keys Key 규칙
- Keys must be unique among siblings. However, it’s okay to use the same keys for JSX nodes in different arrays.
- Keys must not change or that defeats their purpose! Don’t generate them while rendering.
- key는 형제간에 고유해야 합니다. 다른 배열의 JSX 노드에는 동일한 key를 사용해도 괜찮습니다.
- key가 변경되지 않아야 합니다. 그렇지 않으면 목적에 어긋나게 됩니다! 렌더링 중에는 생성하지 마세요.
Why does React need keys? React에 key가 필요한 이유는 무엇일까요?
Imagine that files on your desktop didn’t have names. Instead, you’d refer to them by their order — the first file, the second file, and so on. You could get used to it, but once you delete a file, it would get confusing. The second file would become the first file, the third file would be the second file, and so on. 데스크톱의 파일에 이름이 없다고 상상해 봅시다. 파일 이름 대신 첫 번째 파일, 두 번째 파일 등의 순서로 파일을 참조할 것입니다. 물론 익숙해질 수도 있지만, 파일을 삭제하면 혼란스러워질 수도 있습니다. 두 번째 파일이 첫 번째 파일이 되고, 세 번째 파일이 두 번째 파일이 되는 식으로 말이죠.
File names in a folder and JSX keys in an array serve a similar purpose. They let us uniquely identify an item between its siblings. A well-chosen key provides more information than the position within the array. Even if the position changes due to reordering, the key
lets React identify the item throughout its lifetime.
폴더의 파일 이름과 배열의 JSX key는 비슷한 역할을 합니다. key를 사용하면 형제 항목 사이에서 특정 항목을 고유하게 식별할 수 있습니다. 잘 선택한 key는 배열 내 위치보다 더 많은 정보를 제공합니다. 만약 재정렬로 인해 어떤 항목의 위치가 변경되더라도, 해당 항목이 사라지지 않는 한, React는 key
를 통해 그 항목을 식별할 수 있습니다.
Recap요약
On this page you learned: 이 페이지에서는 이런걸 학습했습니다:
- How to move data out of components and into data structures like arrays and objects.
- How to generate sets of similar components with JavaScript’s
map()
. - How to create arrays of filtered items with JavaScript’s
filter()
. - Why and how to set
key
on each component in a collection so React can keep track of each of them even if their position or data changes.
- 데이터를 컴포넌트에서 배열이나 객체와 같은 데이터 구조로 이동하는 방법.
- JavaScript의
map()
을 사용하여 비슷한 컴포넌트 집합을 생성하는 방법. - JavaScript의
filter()
를 사용하여 필터링된 항목의 배열을 만드는 방법. - 컬렉션의 각 컴포넌트에
key
를 설정해 위치나 데이터가 변경되더라도 React가 각 컴포넌트를 추적할 수 있도록 하는 이유와 방법.
Challenge 1 of 4: Splitting a list in two 목록을 둘로 나누세요
This example shows a list of all people. 이 예제는 모든 사람의 목록을 보여주고 있습니다.
Change it to show two separate lists one after another: Chemists and Everyone Else. Like previously, you can determine whether a person is a chemist by checking if person.profession === 'chemist'
.
이를 Chemists 목록과 그밖의 모든 사람 목록으로 나누어 순서대로 표시하도록 변경하세요. 이전과 마찬가지로 person.profession === 'chemist'
인지 확인함으로써 어떤 사람이 chemist
인지 여부를 결정할 수 있을 것입니다.
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 ( <article> <h1>Scientists</h1> <ul>{listItems}</ul> </article> ); }