React

상품목록을 컴포넌트로 만들기(map 함수)

becky(지은) 2023. 4. 1. 22:42

오늘은 상품목록을 컴포넌트로 만들어볼거예요.

그리고 순차적으로 숫자가 증가하면서, 상품목록이 늘어나는 형태이니

map 함수로 묶어서 간편하게 만들어 볼겁니다

 

 

function App() {
  
  let [shoes]= useState(data)


  return (
    <div className="App">
   //생략
      <Container>
      <Row>
        <Card></Card>
        <Card></Card>
        <Card></Card>
      </Row>
    </Container> 
    </div>
  );
}

export default App;

현재 Card 라는 컴포넌트 3개를 만든 상태입니다.

아직 텅 비어있기 때문에 data 배열에서 정보를 가져와 주어야 해요

 

let data = [
    {
      id : 0,
      title : "White and Black",
      content : "Born in France",
      price : 120000
    },
  
    {
      id : 1,
      title : "Red Knit",
      content : "Born in Seoul",
      price : 110000
    },
  
    {
      id : 2,
      title : "Grey Yordan",
      content : "Born in the States",
      price : 130000
    }
  ] 

export default data;

data는 이렇게 [{0번째 상품정보},{},{}] 배열안에 객체가 들어있는 형태로 생겼어요.

여기서 필요한 객체를 먼저 고르고, 키 값을 적어보면서 정보를 Card 텀포넌트에 넣어볼거예요

참고로, data 가 길어서 새로 data.js 파일을 만들어서 App.js 파일에 import 해주었습니다

 

 

function Card(){
  return (
  <div className="col-md-4">
  <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
  <h4>{ shoes[0].title }</h4>
  <p>{ shoes[0].price }</p>
</div>
)
}

function App (부모컴포넌트) 밖에 function Card(자식컴포넌트)를 선언해주었어요

그리고 부모 컴포넌트 안에 이미 Card 컴포넌트가 존재하니, 그 Card 컴포넌트에다가 뭔가 사부작사부작 만들어보면 되겠죠?

 

 

 

 

 

하지만, 지금 이상태에선 에러가 뜨네요!

shoes 가 not defined 라고 합니다. 부모 컴포넌트에 props를 등록한 후, 자식 컴포넌트에 props 넣어서 써주어야 겠죠?

 

 

 

컴포넌트를 매번 다르게 보여주고 싶으면

props 를 각자 다르게 등록하면 됩니다!!!

 

<Container>
      <Row>
        <Card shoes={shoes[0]}></Card>
        <Card shoes={shoes[1]}></Card>
        <Card shoes={shoes[2]}></Card>
      </Row>
</Container>

function Card(props){
  return (
  <div className="col-md-4">
  <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
  <h4>{ props.shoes.title }</h4>
  <p>{ props.shoes.price }</p>
</div>
)
}

이렇게 props 를 다 다르게 등록하면 (단, 작명은 같아도 됨!!!)

0번째 Card 컴포넌트에는 shoes의 0번째 정보만 들어가고,

1번째 Card 컴포넌트에는 shoes의 1번째 정보만 들어가고,

2번째 Card 컴포넌트에는 shoes의 2번째 정보만 들어갑니다

 

그런데, 사진 정보는 다 같게 나오네요.

<img src=""> 에 변화를 줘야 하는데...

이런 경우에도 props 를 등록하면 됩니다

 

<Container>
      <Row>
        <Card shoes={shoes[0]} i ={1}></Card>
        <Card shoes={shoes[1]} i ={2}></Card>
        <Card shoes={shoes[2]} i ={3}></Card>
      </Row>
    </Container>

data 에 따라 변수 shoes 가 가지는 값이 달라지는 상황과 달리,

그냥 링크에 숫자 1,2,3 을 할당하고 싶은 것이니 props 만 으로도 가능함!

 

 

function Card(props){
  return (
  <div className="col-md-4">
  <img src= {"https://codingapple1.github.io/shop/shoes"+props.i+".jpg"} width="80%" />
  <h4>{ props.shoes.title }</h4>
  <p>{ props.shoes.price }</p>
</div>
)
}

props.i 부분만 달라지니, 일단은 따로 나누어서 더해주면 됩니다.

앞 뒤는 문자열 처리하고요 앞뒤에 {} 붙여줍니다!

 

 

 

 

 

이렇게 이쁘게 완성이 되었습니다!

1. 상품명과 상품가격 등 상품정보를 담은 컴포넌트가 잘 출력이 되고요

2. 상품사진도 상품순서에 맞게 들어가있습니다

 

 

만약 상품이 3개가 아니라.. 100개라면?

 <Container>
      <Row>
        <Card shoes={shoes[0]} i ={1}></Card>
        <Card shoes={shoes[1]} i ={2}></Card>
        <Card shoes={shoes[2]} i ={3}></Card>
        
        ...
      </Row>
    </Container>

이런 코드를 100개 까지 치는 건 무리가 있겠죠?

그래서 map 함수로 묶어서 반복문으로 만들어봅시다!!

<Container>
   <Row>
        {
          shoes.map((a,i)=>{
          return(
            <Card shoes={shoes[i]} i ={i+1}></Card>
          )
          })
        }
   </Row>
</Container>

map 함수는 {} 안에다가

array.map((item,index)=>{

 return (이 코드를 배열의 원소 갯수만큼 실행해줘~!)

})

 

형태로 많이 작성한다. 

item 갯수만큼 코드가 돌고, 뒤에 있는 index, 보통 i는 0부터 1씩 증가하는 정수이다.