[React - Study] 상품목록 컴포넌트화

JooSehyun·2023년 2월 18일
0

[Study]

목록 보기
8/32
post-thumbnail

React - Study

상품목록 컴포넌트화


data.js

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.jsexport하여 App.js에서 import하여 let [shoes] = useState(data) 가져온 상태이다.

App.js

반복문을 사용하기 전 App.jsreturn문 안에는 이렇게 구성이 되어 있었다.

<Container>
      <Row>
          <Col sm>
              <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%;"></img>
              <h4>{shoes[0].title}</h4>
              <p>{shoes[0].content}</p>
          </Col>
          <Col sm>
              <img src="https://codingapple1.github.io/shop/shoes2.jpg" width="100%;"></img>
              <h4>{shoes[1].title}</h4>
              <p>{shoes[1].content}</p>
          </Col>
          <Col sm>
              <img src="https://codingapple1.github.io/shop/shoes3.jpg" width="100%;"></img>
              <h4>{shoes[2].title}</h4>
              <p>{shoes[2].content}</p>
          </Col>
      </Row>
</Container>


연습

나는 일단 map함수를 변수에 담아서 컴포넌트화 시키지 않고 맵함수의 변수를 return문에 넣었다.

let result = shoes.map((a,i)=>{
    return(
          <Col sm>
            <img className='product-img' src={"https://codingapple1.github.io/shop/shoes"+(i+1)+".jpg"} />
            <h4>{a.title}</h4>
            <p>{a.content}</p>
          </Col>
    )
  })
  1. result라는 변수를 만들고 map함수를 담았다.
  2. map함수안에 매개변수 a , i 를 쓰고 return문은 반복될 태그를 작성했다.
  3. img src는 반복적으로 ...shop/shoes1 2,3 가 들어간다. 중괄호안에 쌍따옴표로 감싸주고 1 , 2 , 3 이 들어갈 자리에 index 0 , 1 , 2 가 들어올 자리에 +1한 값을 넣어주었다.
  4. itemtitle 값을 넣어준다.
  5. itemcontent 값을 넣어준다.

그리고 나서 <Container/> 안에 <Row> 안에 맵함수 변수 result를 넣어준다.

      <Container>
        <Row>
          {result}
        </Row>
      </Container>


풀이

<Container>
      <Row>
          <Col sm>
              <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%;"></img>
              <h4>{shoes[0].title}</h4>
              <p>{shoes[0].content}</p>
          </Col>
          <Col sm>
              <img src="https://codingapple1.github.io/shop/shoes2.jpg" width="100%;"></img>
              <h4>{shoes[1].title}</h4>
              <p>{shoes[1].content}</p>
          </Col>
          <Col sm>
              <img src="https://codingapple1.github.io/shop/shoes3.jpg" width="100%;"></img>
              <h4>{shoes[2].title}</h4>
              <p>{shoes[2].content}</p>
          </Col>
      </Row>
</Container>

아까 App.js에 있던 return문이다. 저부분을 컴포넌트화 시켜야하는데 나는 연습으로는 맵함수를 변수로 만들어서 통째로 그냥 그변수를 넣어버렸었는데 풀이는 또다른 방법이다.

우선 하나를 복사하여 함수를 만든다.

function Card( ){ }

function Card(props){
  return(
    <Col sm>
          <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%;"></img>
          <h4>{props.shoes[0].title}</h4>
          <p>{props.shoes[0].content}</p>
    </Col>
  )
}

이렇게 Card함수를 만들고 나서 App.js<Container/> , <Row/> 안에 <Card/>를 넣어준다.

<Container>
        <Row>
          👉<Card/>👈
        </Row>
</Container>

props 로 내려받기

하지만 오류가 뜬다. 왜냐하면 App 컴포넌트에서 shoes라는 state자식 컴포넌트가 받지 못했기 때문이다.
props로 내려주는 방법부터 해보자
let [shoes] = useState(data) 이 값을 자식컴포넌트인 Card에 <Card shoes={shoes}/> 이렇게 내려준다. 작명 = {state} 을 하면되는데 보통 같은 이름을 사용한다. <Card shoes={shoes}/> 그리고
자식 컴포넌트에서는 이렇게 작성한다.
👇👇👇

function Card(props){
  return(
    <Col <sm>
          <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%;"></img>
          <h4>{props.shoes[0].title}</h4>
          <p>{props.shoes[0].content}</p>
    </Col>
  )
}

<Card shoes={shoes}/>props를 전달하고 Card 함수에서 props를 적어주고 h4 , p 태그에 {props.shoes...}로 작성한다.

App.js에서 이렇게 써준다.

<Container>
        <Row>
          <Card shoes={shoes}/>
          <Card shoes={shoes}/>
          <Card shoes={shoes}/> 
        </Row>
</Container>


이렇게 똑같은 상품만 반복되어 나온다.
App.js 를 다시 shoes[x] 로 0 , 1 , 2 순으로 적어주면

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


각 배열에 맞는 titlecontent 가 나타난다. 이미지 경로가 이제 문제인데,
이미지의 경로가 <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%;"></img> 이렇게 shoes 1 .jpg
가 되어있기 때문이다. 각 이미지마다 shoes1.jpg , shoes2.jpg , shoes3.jpg 가 되어야 하기 때문에 <Card shoes={shoes[0] i={1}}> , <Card shoes={shoes[1] i={2}}> , <Card shoes={shoes[2] i={3}}> 으로 넣어준다. 그리고 <Card>에는 img src 도 변경해준다.

<img src="https://codingapple1.github.io/shop/shoes.jpg" width="100%;"></img> 에서
<img src={'https://codingapple1.github.io/shop/shoes'+ props.i +'.jpg'}width="100%;"></img> 로 변경한다.

중간에 숫자가 들어가게 되는 부분을 '' 로 분리시켜주고 중간에 + props.i + 값이 들어오게 된다.

map 함수

우리는 일단 예제의 상품이 3개 밖에 없으니 <Card shoes={shoes[0]}/>를 사용하여 3개를 붙여넣었는데 shoes의 개수 만큼 반복문을 사용하여 shoes가 다음에 더 늘어나거나 줄어들 때를 생각하여 반복문을 넣어 나타나게 하려고한다.

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

이렇게 반복문을 사용하면 shoes의 개수만큼 화면에 잘 나타나지는걸 볼 수 있다.

전체코드

import './App.css';
import {useState} from 'react'
import {Navbar, Container, Nav, Row, Col} from 'react-bootstrap';
import bg from './img/bg.png';
import data from './data';

function App() {

  let [shoes] = useState(data)

  return (
    <div className="App">
        <Navbar bg="dark" variant="dark">
        <Container>
          <Navbar.Brand href="#home">NuyHesShop</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#features">Cart</Nav.Link>
          </Nav>
        </Container>
      </Navbar>
      <div className='main-bg' style={{backgroundImage:'url('+bg+')'}}></div>
      <Container>
        <Row>
          {
            shoes.map((a, i)=>{
              return(
                <Card shoes={shoes[i]} i={i+1}/>
              )
            })
          }
        </Row>
      </Container>
    </div>
  );
}

function Card(props){
  return(
    <Col sm>
          <img src={'https://codingapple1.github.io/shop/shoes'+ props.i +'.jpg'} width="100%;"></img>
          <h4>{props.shoes.title}</h4>
          <p>{props.shoes.content}</p>
    </Col>
  )
}


export default App;

0개의 댓글