본문 바로가기
React/Documentation

리액트 공식 문서 번역-07. 렌더링 목록

by 똘이토스 2023. 7. 9.

데이터 컬렉션에서 여러 유사한 컴포넌트를 표시해야 할 경우가 자주 있습니다. JavaScript 배열 메서드를 사용하여 데이터 배열을 조작할 수 있습니다. 이 페이지에서는 React와 함께 filter()map()을 사용하여 데이터 배열을 필터링하고 변환하여 컴포넌트 배열로 만듭니다.

 

어레이에서 데이터 렌더링

콘텐츠 목록이 있다고 가정합니다.

 

<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>

 

이 목록 항목들 중 유일한 차이점은 그들의 내용, 즉 데이터입니다. 인터페이스를 구축할 때 동일한 컴포넌트의 여러 인스턴스를 다른 데이터를 사용하여 표시해야 하는 경우가 자주 있습니다. 댓글 목록에서 프로필 이미지 갤러리까지 다양한 상황에서 JavaScript 객체와 배열에 데이터를 저장하고, map()filter()와 같은 메서드를 사용하여 컴포넌트의 목록을 렌더링할 수 있습니다.

 

다음은 배열에서 항목 목록을 생성하는 방법의 간단한 예입니다

 

1. 데이터를 배열로 이동하세요

const people = [
  'Creola Katherine Johnson: mathematician',
  'Mario José Molina-Pasquel Henríquez: chemist',
  'Mohammad Abdus Salam: physicist',
  'Percy Lavon Julian: chemist',
  'Subrahmanyan Chandrasekhar: astrophysicist'
];

 

2. people 멤버들을 새로운 JSX 노드 배열 listItems로 매핑합니다.

const listItems = people.map(person => <li>{person}</li>);

 

3. 컴포넌트에서 <ul>로 감싼 listItems를 반환합니다.

return <ul>{listItems}</ul>;

 

https://codesandbox.io/s/nd9t9q?file=/App.js&utm_medium=sandpack

 

muddy-thunder-nd9t9q - CodeSandbox

muddy-thunder-nd9t9q using react, react-dom, react-scripts

codesandbox.io

 

위의 샌드박스에서 콘솔 오류를 확인할 수 있습니다

 

Warning: Each child in a list should have a unique “key” prop.

 

이 오류를 나중에 이 페이지에서 해결하는 방법을 배우겠습니다. 그 전에 데이터에 구조를 추가해 보겠습니다.

 

항목 배열 필터링

이 데이터는 훨씬 더 구조화될 수 있습니다.

 

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',
}, {
  name: 'Percy Lavon Julian',
  profession: 'chemist',  
}, {
  name: 'Subrahmanyan Chandrasekhar',
  profession: 'astrophysicist',
}];

 

'chemist’인 사람들만 표시하고 싶다면 어떻게 해야 할까요? 이를 위해 JavaScript의 filter() 메서드를 사용하여 해당하는 사람들만 반환할 수 있습니다. 이 메서드는 항목의 배열을 가져와 "테스트"를 통과한 (true 또는 false를 반환하는 함수) 항목만 새로운 배열로 반환합니다.

 

'chemist’ 직업을 가진 사람들만 필터링하려면 어떻게 해야 할까요? 이를 위한 "테스트" 함수는 (person) => person.profession === 'chemist'와 같이 작성됩니다. 다음은 위 내용을 구현한 코드입니다

 

1. people에서 person.profession === 'chemist'를 만족하는 항목만 골라 새로운 배열 chemists를 만듭니다. 이를 위해 people 배열에 filter()를 호출합니다

const chemists = people.filter(person =>
  person.profession === 'chemist'
);

 

2. chemists 를 map

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>
);

 

3. 마지막으로, 컴포넌트에서 listItems를 반환합니다

return <ul>{listItems}</ul>;

 

https://codesandbox.io/s/mr7kbm?file=/App.js&utm_medium=sandpack

 

ecstatic-elion-mr7kbm - CodeSandbox

ecstatic-elion-mr7kbm using react, react-dom, react-scripts

codesandbox.io

 

화살표 함수는 => 다음에 오는 표현식을 암묵적으로 반환하기 때문에 return 문을 사용하지 않아도 됩니다

 

const listItems = chemists.map(person =>
  <li>...</li> // Implicit return!
);

 

하지만 => 다음에 { 중괄호가 따라온다면 명시적으로 return을 작성해야 합니다!

 

const listItems = chemists.map(person => { // Curly brace
  return <li>...</li>;
});

 

=> {를 포함한 화살표 함수는 "블록 바디"라고 합니다. 이를 사용하면 여러 줄의 코드를 작성할 수 있지만 return 문을 직접 작성해야 합니다. 만약 return을 작성하지 않으면 아무것도 반환되지 않습니다!

 

key를 사용하여 목록 항목의 순서를 유지하기

위의 모든 샌드박스에서 콘솔에 오류가 표시되는 것에 유의하세요

 

Warning: Each child in a list should have a unique “key” prop.

 

각 배열 항목에는 해당 항목이 배열의 다른 항목들과 구별될 수 있는 문자열 또는 숫자로 구성된 고유한 key를 지정해야 합니다.

 

<li key={person.id}>...</li>
💡 map() 호출 내부에 직접 포함된 JSX 요소는 항상 key가 필요합니다!

 

각 키는 해당 컴포넌트가 어떤 배열 아이템에 해당하는지 React에게 알려주어 나중에 일치시킬 수 있도록 합니다. 배열 아이템이 이동(예: 정렬), 삽입, 삭제될 수 있는 경우 이러한 key 는 React가 일어난 일을 정확하게 추론하고 DOM 트리에 올바른 업데이트를 수행하는 데 중요합니다.

 

키를 런타임에서 생성하는 대신, 데이터에 포함시키는 것이 좋습니다

 

https://codesandbox.io/s/nw8on9?file=/data.js&utm_medium=sandpack

 

laughing-dirac-nw8on9 - CodeSandbox

laughing-dirac-nw8on9 using react, react-dom, react-scripts

codesandbox.io

 

각 리스트 항목에 대해 여러 DOM 노드를 표시하기

더보기

각 항목마다 하나 이상의 DOM 노드를 렌더링해야 하는 경우에는 어떻게 해야 할까요?

 

짧은 <>...</> 프래그먼트 구문은 키를 전달할 수 없으므로 하나의 <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는 DOM에서 사라지기 때문에 이것은 <h1>, <p>, <h1>, <p>와 같은 평면 목록을 생성합니다.

 

key를 어디에서 가져와야 할까요?

데이터의 출처에 따라 고유한 key를 생성하는 방법이 달라집니다

  • 데이터베이스에서 가져온 데이터 : 데이터가 데이터베이스에서 가져온 경우, 고유성을 자연스럽게 가지고 있는 데이터베이스 키/ID를 사용할 수 있습니다.
  • 로컬에서 생성한 데이터 : 데이터가 로컬에서 생성되고 유지되는 경우 (예: 메모 앱의 메모), 증가하는 카운터, crypto.randomUUID() 또는 uuid와 같은 패키지를 사용하여 항목을 생성합니다.

 

key의 규칙

  • 키는 형제 요소들 사이에서 유일해야합니다. 그러나 서로 다른 배열의 JSX 노드에서 동일한 키를 사용하는 것은 괜찮습니다.
  • 키는 렌더링 중에 생성하지 마십시오. 그렇게하면 키의 목적이 무효화됩니다! 키는 변경해서는 안됩니다!

 

React에 키가 필요한 이유는 무엇입니까?

상상해보세요. 데스크탑에 파일들이 이름 대신 순서로만 구분된다면 어떨까요? 첫 번째 파일, 두 번째 파일, 이런 식으로 말이죠. 그것에 익숙해지겠지만, 파일을 삭제하면 혼란스러워질 것입니다. 두 번째 파일이 첫 번째 파일이 되고, 세 번째 파일이 두 번째 파일이 되는 식으로 말이죠.

 

폴더 안에 있는 파일 이름과 JSX 배열의 키는 비슷한 역할을 합니다. 이것들은 형제 관계에서 항목을 고유하게 식별할 수 있게 해줍니다. 잘 선택된 키는 배열 내 위치보다 더 많은 정보를 제공합니다. 위치가 재정렬되어도 키를 통해 React는 항목을 생명주기 동안 식별할 수 있습니다.

 

💡 배열 항목의 인덱스를 키로 사용하려는 유혹을 느낄 수 있습니다. 사실, 키를 지정하지 않으면 React는 항목의 인덱스를 사용합니다. 하지만 배열에서 항목이 추가, 삭제 또는 재정렬되면 렌더링 순서가 변경됩니다. 인덱스를 키로 사용하면 종종 미묘하고 혼란스러운 버그를 일으킵니다.

마찬가지로 key={Math.random()}와 같이 키를 동적으로 생성하지 마세요. 이렇게 하면 렌더링 사이에서 키가 일치하지 않아 모든 구성 요소와 DOM이 매번 다시 생성되어 성능 저하와 리스트 아이템 내의 사용자 입력을 잃게 됩니다. 대신 데이터를 기반으로 안정적인 ID를 사용하세요.

키는 React 자체에서 힌트로만 사용되므로 구성 요소는 키를 prop으로 받지 않습니다. 구성 요소가 ID가 필요한 경우 별도의 prop으로 전달해야 합니다. 예를 들어, <Profile key={id} userId={id} />와 같이 전달합니다.

 

요약

  • 컴포넌트 내의 데이터를 배열이나 객체와 같은 데이터 구조체로 이동시키는 방법.
  • 자바스크립트의 map()을 사용하여 유사한 컴포넌트 세트를 생성하는 방법.
  • 자바스크립트의 filter()를 사용하여 필터링된 항목 배열을 생성하는 방법.
  • 컬렉션의 각 컴포넌트에 key를 설정하여 위치나 데이터가 변경되더라도 React가 각각을 추적할 수 있도록하는 이유와 방법.

 

2023.07.10 - [React/Documentation] - 리액트 공식 문서 번역-08. 컴포넌트 순수성 유지하기

 

리액트 공식 문서 번역-08. 컴포넌트 순수성 유지하기

일부 JavaScript 함수는 순수 함수(pure function)입니다. 순수 함수는 계산만 수행하고 그 이상의 작업을 수행하지 않습니다. 컴포넌트를 순수 함수로 엄격하게 작성함으로써 코드베이스가 커져도 이

ddor2.tistory.com