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.js
를 export
하여 App.js
에서 import
하여 let [shoes] = useState(data)
가져온 상태이다.
App.js
반복문을 사용하기 전 App.js
의 return
문 안에는 이렇게 구성이 되어 있었다.
<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>
)
})
result
라는 변수를 만들고 map함수
를 담았다.map함수
안에 매개변수 a
, i
를 쓰고 return
문은 반복될 태그를 작성했다.img src
는 반복적으로 ...shop/shoes1
2,3
가 들어간다. 중괄호안에 쌍따옴표로 감싸주고 1 , 2 , 3 이 들어갈 자리에 index 0 , 1 , 2
가 들어올 자리에 +1한 값을 넣어주었다.item
의 title
값을 넣어준다.item
의 content
값을 넣어준다.그리고 나서 <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>
하지만 오류가 뜬다. 왜냐하면 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]}/>
각 배열에 맞는title
과content
가 나타난다. 이미지 경로가 이제 문제인데,
이미지의 경로가<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 +
값이 들어오게 된다.
우리는 일단 예제의 상품이 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;