피리부는 사나이 (pied piper)

[React] map으로 컴포넌트 리스트 만들기 본문

React

[React] map으로 컴포넌트 리스트 만들기

코더 451 2022. 7. 25. 16:09

한 번에 수많은 데이터가 존재한다면, 같은 코드를 단순하게 반복하여 작성할 수 있다.

하지만 매우 비효율적이다.

 

이때 map 함수를 이용하면 효율적으로 데이터 결과를 나타낸 컴포넌트 리스트를 만들 수 있다.

 

 

map() 메서드는 리스트 내 모든 요소 각각에 대하여 함수를 호출한 결과를 모아 새로운 배열을 반환한다.
[리스트].map((i) => {return 로직}

 

function App() {
  return <Hello name="Michael" />;
}

function Hello(props) {
  const name = props.name;
  const num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; //1~10호를 만들 것입니다.

  // list map을 이용하여 h1 태그들의 리스트를 만듭니다.
  const numComponentsArray = num.map((i) => (
    <h1>
      안녕, {name} {i}호
    </h1>
  ));

  return <div>{numComponentsArray}</div>;
}

export default App;

 

결과 

 

간결한 코드와 아름다운 결과를 볼 수 있다.

 

하지만 여기서 한 가지 문제점이 생긴다.

 

 

"리스트 각 요소가 고유한 key 값을 가지지 않았어요"

키값을 넣어줘야하는 이유는 무엇인가?



리액트에서 렌더링 작업을 진행했을 때 어떤 요소에 변동있으면 그 요소만 새로 그려주기 위해서

만약에 key 값이 없으면 하나의 요소가 변경되어도 array에 담긴 요소를 모두 그려주기때문에 비효율적이다.

 

+ 키값은 보통 배열의 id 값을 넣어줌, 교유의 값이 없다면 index를 key로 사용하면 되지만, 나중에 순서와 관련된 문제 발생하기 때문에,

권장하진 않음

더보기

key 값은 동일한 컴포넌트 리스트에서만 '유일값'이면 됨

 

키값을 넣은 버전 

 

function App() {
  return <Hello name="Michael" />;
}

function Hello(props) {
  const name = props.name;
  const num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; //1~10호를 만들 것입니다.

  // list map을 이용하여 h1 태그들의 리스트를 만듭니다.
  const numComponentsArray = num.map((i) => (
    <h1 key={i.toString()}>
      안녕, {name} {i}호
    </h1>
  ));

  return <div>{numComponentsArray}</div>;
}

export default App;

 

 

 

# key가 있을 경우와 없을 경우 React의 동작 방식

 

### 키가 없을 때

만약 여기서 <h2>안녕, 개리 2호</h2> 를 제거한다면 리액트는 어떻게 컴포넌트를 바꿔줄까요?

<h2>안녕, 개리 1호</h2>
<h2>안녕, 개리 2호</h2>
<h2>안녕, 개리 3호</h2>
<h2>안녕, 개리 4호</h2>

리액트는 개리 1호부터 4호까지의 트리 요소를 모두 비교한 후, 개리 2호, 개리 3호, 개리 4호 h2태그를 모두 변경하게 될 것입니다.

<h2>안녕, 개리 1호</h2>
<h2>안녕, 개리 3호</h2>
<h2>안녕, 개리 4호</h2>

'안녕, 개리 2호'를 지우고 '안녕, 개리 3호'를 만듭니다.

'안녕, 개리 3호'를 지우고 '안녕, 개리 4호'를 만듭니다.

'안녕, 개리 4호'를 지웁니다.

위 코드에서 변화된 것은 개리 2호가 제거된 것과 개리 3호, 4호의 위치입니다. 하지만 리액트가 느끼기에는 개리 2, 3, 4호가 모두 변경되었다고 생각합니다. 3, 4호가 존재하고 있는데 말이죠. 그래서 2, 3, 4호 h2 태그를 새롭게 그립니다.

### 키가 있을 때

<h2 key="1">안녕, 개리 1호</h2>
<h2 key="2">안녕, 개리 2호</h2>
<h2 key="3">안녕, 개리 3호</h2>
<h2 key="4">안녕, 개리 4호</h2>
<h2 key="1">안녕, 개리 1호</h2>
<h2 key="3">안녕, 개리 3호</h2>
<h2 key="4">안녕, 개리 4호</h2>

위와 같이 나열된 요소에서 key 속성을 넣어줬을 때, 리액트는 어떻게 컴포넌트를 바꿔줄까요? 리액트는 key를 통해 기존 트리 요소와 이후 트리 요소들이 일치하는지 확인합니다.

  • key가 2인 요소가 존재하지 않으니, '안녕, 개리 2호'를 지웁니다.
  • key가 3인 요소, key가 4인 요소는 존재하는데 위치만 다른 것을 알고, '안녕, 개리 3호', '안녕, 개리 4호'의 위치를 옮겨줍니다. 지우고 다시 생성하지 않고 말이죠.

 

 

 

 

4. 실제 적용해보기 : 다음과 같은 data가 있다고 했을 때 아래와 같은 화면이 되려면 어떻게 해야 할까?

 

 

 

코드 구현 

import React from "react";

const Home = () => {
  const productList = {
    products: [
      {
        title: "개발자 무릎 담요",
        price: 17500,
        id: 101,
      },
      {
        title: "Hack Your Life 개발자 노트북 파우치",
        price: 29000,
        id: 102,
      },
      {
        title: "우당탕탕 라이켓의 실험실 스티커북",
        price: 29000,
        id: 103,
      },
      {
        title: "버그를 Java라 버그잡는 개리씨 키링",
        price: 29000,
        id: 104,
      },
    ],
  };

  return (
    <>
      {productList.products.map((item, idx) => (
        <li
          key={item.id}
          style={{
            listStyle: "none",
          }}
        >
            <h2>
              {idx + 1} {item.title}
            </h2>
            <span>{`${item.price}원`}</span>
        </li>
      ))}
    </>
  );
};

export default Home;

 

'React' 카테고리의 다른 글

[React] useRef  (0) 2022.07.27
Comments