전에 배운 map함수를 리액트에서 컴포넌트에서 활용이 가능하다.
먼저 최상위 컴포넌트인 App.js
가 있고 하위 컴포넌트들로 Card
, CardList
, SearchBox
컴포넌드가 있다.
class App extends Component {
state={
monsters : [], // 백엔드로부터 받는 monster데이터를 monsters에 담는다.
userInput : ""
}
}
render(){
return(
<div className="App">
<h1>컴포넌트 재사용 연습</h1>
<CardList />
</div>
)
}
⬆︎초기 App.js
의 상태이다.
⬇︎먼저 백엔드로부터 데이터를 받기위해 componentDidMount()
내부에서 fetch()
를 실행한다.
class App extends Component {
state={
monsters : [], // 백엔드로부터 받는 monster데이터를 monsters에 담는다.
userInput : ""
}
}
componentDidMount(){
fetch(""https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(response => this.setState({
monseters : response
})
);
}
//fetch로 받은 데이터는 setState로 monsters에 저장한다.
render(){
return(
<div className="App">
<h1>컴포넌트 재사용 연습</h1>
<CardList />
</div>
)
}
api로부터 받은 데이터는 객체로 이루어진 배열로서, 10마리의 몬스터 정보들이 각각의 객체에 담겨있다.
[ { "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "Sincere@april.biz", "address": { "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", "geo": { "lat": "-37.3159", "lng": "81.1496" } }, "phone": "1-770-736-8031 x56442", "website": "hildegard.org", "company": { "name": "Romaguera-Crona", "catchPhrase": "Multi-layered client-server neural-net", "bs": "harness real-time e-markets" } }, "---------밑은 생략----------" ]
App.js
에서 monsters에 데이터를 저장후에 이 데이터를 자식 컴포넌트인 <CardList />
에 props로 전달한다. (예시: <CardList monsters={this.state.monsters} />
)
// App.js 컴포넌트의 render 부분
render(){
const {monsters, userInput} = this.state // 비구조화 할당을 해준다.
return (
<div className="App">
<CardList monsters={monsters} />
// this.state.monsters에 담긴 데이터를 CardList에 전달
//비구조화 할당을 했기 때문에 mostsers만 쓴다.
</div>
)
}
App.js
에서 props로 받은 데이터를 CardList
에서 map()
를 이용하여 Card
컴포넌트를 반환시킨다.
전달받은 props는 monsters이고 monsters에는 App.js
에서 이미 fetch()
로 백엔드에서 받은 데이터가 들어있다.
// CardList 컴포넌트
class CardList extends Component {
render() {
return (
<div className='card-list'>
{this.props.monsters.map((data, index) => {
return (
<Card
key={index}
id={data.id}
name={data.name}
email={data.email}
/>
);
})}
</div>
);
}
}
monsters는 10마리의 몬스터 정보가 한 마리당 한 객체로 이루어져 있는 배열이다. 즉 10개의 객체로 이루어진 배열![{...},{...},{...},{...}......]
.
map()
를 통해 각각의 객체에 차례대로 접근하고 그 객체안에서 우리가 필요한 id
, name
, email
값에 접근하여 <Card id={data.id} name={data.name} email={data.email} />
이렇게 Card컴포넌트의 props
로 부여한다. 이렇게 map()
함수가 각 객체에 한 번씩 총 10번을 실행면서 10장의 각각의 Monster Cards가 만들어진다.
//Card 컴포넌트에서는 CardList에서 map()으로 전달한 id, name, email props를 받는다.
class Card extends Component {
render(){
const {id, name, email} = this.props // 비구조화 할당!!
return (
<div className="Card">
<img src={`https://robohash.org/${id}?set=set2&size=180x180`} alr="" />
<h2>{name}</h2>
<p>{email}</p>
//CardList로 부터 받은 props를 받아서 리턴!
</div>
)
}
}
CardList에서는 map()으로 10번의 데이터를 전달하기 때문에 Card도 10장의 다른 Monster Cards가 생기게 된다.
카드 한장이 <Card />
컴포넌트이다. <CardList />에서
map()
을 통해 10번의 id
, name
, email
을 <Card />
로 전달하여 10장의 카드가 나온 것!
이렇게 map()
을 통해서 코드는 획기적으로 줄이면서도 수십 수백 수천의 데이터를 나타낼 수 있게 된다 🙂