[React] 컴포넌트 반복하기

파송송계란빡 ㅣ 2022. 6. 20. 14:28

🌟 컴포넌트 반복

https://ko.reactjs.org/docs/lists-and-keys.html

 

리스트와 Key – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

🔖 map()

  • 배열 요소를 일괄 변경
  • Array의 객체를 map 메소드로 활용 → callback 함수를 인자로 받아, callback 함수의 return으로 반환되는 값들을 재조합하여 새로운 배열을 생성

예시1

const arr = [
    {id: 0, name: '혜림', age:6},
    {id: 1, name: '현아', age:3},
    {id: 2, name: '지우', age:2},
    {id: 3, name: '우림', age:5},
]

const arr2 = arr.map(el => {
    el.age = el.age + 1
    return el
})

 

예시2

const arr = [
    {id: 0, name: '혜림', age:6},
    {id: 1, name: '현아', age:3},
    {id: 2, name: '지우', age:2},
    {id: 3, name: '우림', age:5},
]

const arr3 = arr.map(el => el.name)

 

🔖 map() 이용하기 - 바로 return으로 컴포넌트 전달

배열에 있는거 하나씩 꺼내서 컴포넌트 만들어주기

pickedCards만큼 반복해서 props로 전달해주기

바로 리턴해서 컴포넌트로 만들어줄 수 있다.

/*App.js*/
import React, { useEffect, useState } from "react";
import datas from "./data/cards"
import BusinessCard from "./components/BusinessCard";

// 추첨하기 버튼과 컴포넌트를 구현
// 추첨하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
export default function App() {
  const [cards, setCards] = useState([])
  const [pickedCards, setPickedCards] = useState([])

  function draw() {
    //추천하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
    const randomIdx = Math.floor(Math.random() * cards.length)    //배열의 길이 중 10개 인덱스 무작위로 뽑기
    const randomItem = cards[randomIdx]                           //랜덤 인덱스로 배열 값 가져오기

    //이미 뽑은 사람의 개수가 2인 경우
    if (pickedCards.length > 2) {
      const names = pickedCards.reduce((acc, cur) => {
        return acc = acc.concat(`${cur.name}, 입니다.`)
      }, "")
      alert(names)
      return
    }

    //중복 뽑기를 방지하기 위해 뽑힌건 제거
    setCards(cards.filter(                                        //배열을 돌면서, 조건에 맞는 배열을 새로 만들어준다,
      (c) =>
        c.phoneNumber !== randomItem.phoneNumber
    ))

    setPickedCards([...pickedCards, randomItem])                  //기존에 있던 배열 복사 + 새로 뽑은 사람
  }

  useEffect(() => {     //처음 렌더 되었을 때, 데이터 한번 호출
    setCards(datas)
  }, [])

  return (
    <div>
      {cards.length > 0 && <button onClick={draw}>추첨하기</button>}
      {/* {pickedCards.length > 0 && (
        <BusinessCard info={pickedCards[pickedCards.length - 1]}></BusinessCard>
      )} */}
      {
        pickedCards.length > 0 && pickedCards.map(pickedCard =>
          <BusinessCard info={pickedCard}></BusinessCard>
        )
      }

    </div >
  );
}

 

🔖 map() 이용하기 - 변수에 한번 저장했다가 컴포넌트 전달

결과값을 변수에 저장해서 저장한 값을 컴포넌트에 추가 할 수도 있다.

/*App.js*/
import React, { useEffect, useState } from "react";
import datas from "./data/cards"
import BusinessCard from "./components/BusinessCard";

// 추첨하기 버튼과 컴포넌트를 구현
// 추첨하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
export default function App() {
  const [cards, setCards] = useState([])
  const [pickedCards, setPickedCards] = useState([])

  function draw() {
    //추천하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
    const randomIdx = Math.floor(Math.random() * cards.length)    //배열의 길이 중 10개 인덱스 무작위로 뽑기
    const randomItem = cards[randomIdx]                           //랜덤 인덱스로 배열 값 가져오기

    //이미 뽑은 사람의 개수가 2인 경우
    if (pickedCards.length > 2) {
      const names = pickedCards.reduce((acc, cur) => {
        return acc = acc.concat(`${cur.name}, 입니다.`)
      }, "")
      alert(names)
      return
    }

    //중복 뽑기를 방지하기 위해 뽑힌건 제거
    setCards(cards.filter(                                        //배열을 돌면서, 조건에 맞는 배열을 새로 만들어준다,
      (c) =>
        c.phoneNumber !== randomItem.phoneNumber
    ))

    setPickedCards([...pickedCards, randomItem])                  //기존에 있던 배열 복사 + 새로 뽑은 사람
  }

  useEffect(() => {     //처음 렌더 되었을 때, 데이터 한번 호출
    setCards(datas)
  }, [])

  const result = pickedCards.map((pickedCard) =>
    <BusinessCard info={pickedCard} />)

  return (
    <div>
      {cards.length > 0 && <button onClick={draw}>추첨하기</button>}
      {/* {pickedCards.length > 0 && (
        <BusinessCard info={pickedCards[pickedCards.length - 1]}></BusinessCard>
      )} */}
      {
        pickedCards.length > 0 && result
      }

    </div >
  );
}

 

🔖 key가 없다고 에러 뜬다.

 

🔖 key는 왜 필요한가?

  • Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다.
  • key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.
  • Key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것입니다.
  • 대부분의 경우 데이터의 ID를 key로 사용합니다.
  • React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인합니다.
  • 해당 key는 오로지 형제 사이에서만 유일하면 되고, 전역에서 유일할 필요는 없습니다.
  • 조금 더 디테일한 key 사용 이유

https://ko.reactjs.org/docs/reconciliation.html#recursing-on-children

 

재조정 (Reconciliation) – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

🔖 key를 추가

  • key를 추가했더니 더이상 에러 발생 하지 않음

 

[React] 컴포넌트 반복하기