4장
4. 슈퍼 똑똑하게 컴포넌트 만들기
4.1 비슷한 컴포넌트 여러 개 만들기
import React from 'react';
function Food({fav}) {
return <h1> I like {fav}</h1>;
}
function App() {
return (
<div>
<h1>Hello!!!</h1>
<Food fav="kimchi" />
<Food fav="오징어" />
<Food fav="돈까스" />
</div>
)
}
export default App;
-
매번
<Food/><Food/><Food/>..와 같이 직접 입력하는 것은 효율적이지 않다. -
음식 데이터가 1000개이면 1000개를 반복 작성해야 하는 문제가 있다.
-
서버에거 넘어온 데이터를 저장할 수 있도록 foodLike라는 변수를 만들고 빈 배열을 할당한다.
-
한 땀 한 땀 입력한 Food 컴포넌트는 삭제한다.
import React from 'react';
function Food({fav}) {
return <h1> I like {fav}</h1>;
}
const foodLike = [];
function App() {
return (
<div>
<h1>Hello!!!</h1>
</div>
)
}
export default App;
- 서버에서 데이터가 넘어온다고 상상하면서 코드를 작성한다.
import React from 'react';
function Food({fav}) {
return <h1> I like {fav}</h1>;
}
const foodLike = [
{
name: 'kimchi',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzvpLBoWT6py96qHadIU8w2FkrfhUI4V06cK7uAC8USybTK2s&usqp=CAc',
},
{
name: 'Hotdog',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQPiH-PuoDAHJFXxjimB4E2jR5Uqv-9fJjayn6N19-Bq83vn8rEOUI2_5hExg&usqp=CAc',
},
];
function App() {
return (
<div>
<h1>Hello!!!</h1>
</div>
)
}
export default App;
4.2 map() 함수로 컴포넌트 많이 만들기
- 구글 콘솔에서 다음 자바스크립트 코드를 작성한다.
const friends = ["dal", "mark", "lynn", "japan guy"]
friends.map(current => {
console.log(current); // 여기서 current가 출력되고
return 0; // 여기서 0을 반환한다.
})
/*
dal
mark
lynn
japan guy
[0, 0, 0, 0]
*/
- map()함수의 2가지 특징
- map()함수의 인자로 전달한 함수는 배열 friends의 원소를 대상으로 실행된다. 여기서는 4번 실행된다.
- 함수가 반환한 값이 모여 배열이 되고, 그 배열이 map()함수의 반환값이 된다.
- current 인자에 하트를 추가하여 반환하면 친구들 이름에 하트가 추가된 배열을 만들 수 있을 것 같다.
friends.map(function(friend) {
return friend + "♥"
})
// ["dal♥", "mark♥", "lynn♥", "japan guy♥"]
- map()함수로 Food 컴포넌트 많이 만들어 보기
import React from 'react';
function Food({ name }) {
return <h1> I like {name}</h1>;
}
const foodLike = [
{
name: 'kimchi',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzvpLBoWT6py96qHadIU8w2FkrfhUI4V06cK7uAC8USybTK2s&usqp=CAc',
},
{
name: 'Hotdog',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQPiH-PuoDAHJFXxjimB4E2jR5Uqv-9fJjayn6N19-Bq83vn8rEOUI2_5hExg&usqp=CAc',
},
{
name: '김밥',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSzk3v5BkeSeALfIeOLBSx9cMqgAEMSAzN0Qg&usqp=CAU',
},
];
function App() {
return (
<div>
{foodLike.map(dish=> (<Food name={dish.name}/>))}
</div>
// foodLike 배열에 있는 원소가 하나씩 Food 컴포넌트으 props원소로 넘어간다.
)
}
export default App;
- 이미지 추가
import React from 'react';
function Food({ name, picture }) {
return (
<div>
<h2>I like {name}</h2>
<img src={picture} />
</div>
);
}
const foodLike = [
// 생략
];
function App() {
return (
<div>
{foodLike.map(dish=> (<Food name={dish.name} picture={dish.image} />))}
</div>
)
}
export default App;
- 결과

4.3 음식 앱 이리저리 만지고, 고쳐보기
- map() 함수의 인자로 함수를 전달하기
import React from 'react';
function Food({ name, picture }) {
// 생략 ..
}
const foodLike = [
// 생략 ..
];
function renderFood(dish) {
return <Food name={dish.name} picture={dish.image} />;
}
// 화살표 함수로 renderFood 작성
const renderFood = dish => <Food name={dish.name} picture={dish.image} />;
function App() {
return (
<div>
{foodLike.map(renderFood)}
</div>
)
}
export default App;
- Warning: Each child in a list should have a unique “key” prop.
- 원복하고 경고를 콘솔에 나오는 경고 제거하기
- FoodLike 원소에 id값을 추가
- Food 컴포넌트에 id 전달
- 리액트는 Food 컴포넌트가 서로 다르다는 걸 알 방법이 없기 때문에 이렇게 알려준다.
- img에 alt 속성을
{name}을 넣고 두 번째 경고를 없앤다.
import React from 'react';
function Food({ name, picture }) {
return (
<div>
<h2>I like {name}</h2>
<img src={picture} alt={name} />
</div>
);
}
const foodLike = [
{
id: 1,
name: 'kimchi',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzvpLBoWT6py96qHadIU8w2FkrfhUI4V06cK7uAC8USybTK2s&usqp=CAc',
},
{
id: 2,
name: 'Hotdog',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQPiH-PuoDAHJFXxjimB4E2jR5Uqv-9fJjayn6N19-Bq83vn8rEOUI2_5hExg&usqp=CAc',
},
{
id: 3,
name: '김밥',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSzk3v5BkeSeALfIeOLBSx9cMqgAEMSAzN0Qg&usqp=CAU',
},
];
function App() {
return (
<div>
{foodLike.map(dish=> (<Food key={dish.id} name={dish.name} picture={dish.image} />))}
</div>
)
}
export default App;
4.3 음식 앱에 prop-types 도입하기
- prop-types는 props의 자료형을 검사할 수 있게 도와주는 도구이다.
- prop-types를 설치한다.
npm install prop-types- package.json에 dependencies 키에 있는 값에 prop-types가 있으면 설치가 잘 된 것이다.
- 음식앱에 평점을 추가하고 자료형을 검사한다.
import React from 'react';
import PropTypes from 'prop-types';
function Food({ name, picture, rating }) {
return (
<div>
<h2>I like {name}</h2>
<h4>{rating}/5.0</h4>
<img src={picture} alt={name} />
</div>
);
}
const foodLike = [
{
id: 1,
name: 'kimchi',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzvpLBoWT6py96qHadIU8w2FkrfhUI4V06cK7uAC8USybTK2s&usqp=CAc',
rating: 5.0,
},
{
id: 2,
name: 'Hotdog',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQPiH-PuoDAHJFXxjimB4E2jR5Uqv-9fJjayn6N19-Bq83vn8rEOUI2_5hExg&usqp=CAc',
rating: 3.2,
},
{
id: 3,
name: '김밥',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSzk3v5BkeSeALfIeOLBSx9cMqgAEMSAzN0Qg&usqp=CAU',
rating: 4.9,
},
];
function App() {
return (
<div>
{foodLike.map(dish=> (<Food key={dish.id} name={dish.name} picture={dish.image} rating={dish.rating} />))}
</div>
)
}
Food.propTypes = {
name: PropTypes.string.isRequired,
picture: PropTypes.string.isRequired,
rating: PropTypes.string.isRequired,
}
export default App;
- 콘솔에서 경고가 발생한다.
rating은 number타입이기 때문이다.rating: PropTypes.number.isRequired,경고가 사라진다.
- Food 컴포넌트에 전달하는 picture를 image로 변경해도 경고를 발생시킨다.
- 자료형과 그 이름의 값이 전달되었는지도 검사한다.
- 평점은 나중에 입력할 수 있기 때문에
rating의 isRequired는 빼도 된다.isRequied를 뺴면 필수는 아니지만 자료형은number타입을 전달해야 한다.
- prop-type 공식문서