본문 바로가기
Project/REACT

9 - 발전된 컴포넌트 만들기(1)

by Elfen Lied 2020. 12. 10.
반응형
  • 비슷한 컴포넌트 여러 개 만들기
  • map() 함수로 컴포넌트 많이 만들기

1. 비슷한 컴포넌트 여래 개 만들기

App.js 파일을 열어서 코드가 효율적인지 확인해본다.

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="ramyun" />
      <Food fav="samgiopsal" />
      <Food fav="chukumi" />
    </div>
  );
}

export default App;

해당 코드는 효율적이지 않다.

음식 추가할 때 마다 <Food fav="..." /> 를 복사 해줘야 하기 때문이다.

음식 데이터 받아 출력할 경우에 음식 데이터 개수를 알 수 없으면 더 문제가 된다.

 

앞서 서버에서 데이터 받아 오는 방법을 알아본다.

 

 

- 음식 데이터 만들기

1. 서버에서 넘어온 데이터를 저장할 수 있게 foodLike 변수를 만들어 빈 배열에 할당한다.

앞전에 적어놓은 <Food fav="kimchi" /> 등등은 다 삭제한다.

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;

 

2. 서버에서 데이터가 넘어왔다 생각하고 다음 코드를 작성한다.

image 키값은 인터넷에서 찾은 이미지 주소를 복사해서 넣는다. (이미지에 마우스 우클릭 이미지 주소 복사)

import React from 'react';

function Food({ fav }) {
  return <h1>I like {fav}</h1>;
}

const foodLike = [
  {
    name: 'Kimchi',
    image: 'https://cdn.pixabay.com/photo/2019/07/25/01/35/kimchi-4361465_1280.jpg',
  },
  {
    name: 'Samgyeopsal',
    image: 'https://cdn.pixabay.com/photo/2017/05/18/10/48/pork-2323228_1280.jpg',
  },
  {
    name: 'Bibimbap',
    image: 'https://cdn.pixabay.com/photo/2017/08/08/09/44/food-photography-2610863_1280.jpg',
  },
  {
    name: 'Doncasu',
    image: 'https://cdn.pixabay.com/photo/2016/09/23/23/23/restaurant-1690696_1280.jpg',
  },
  {
    name: 'Kimbap',
    image: 'https://cdn.pixabay.com/photo/2015/03/24/07/07/kim-rice-687172_1280.jpg',
  },
];

function App() {
  return (
    <div>
      <h1>Hello</h1>      
    </div>
  );
}

export default App;

해당 이미지는 픽사베이에서 가져왔음.

 

 

2. map() 함수로 컴포넌트 많이 만들기

map() 함수 동작을 알아보기 위해 콘솔을 사용함 (브라우저에서 F12 개발자 도구)

 

 

- map() 함수 사용법 알아보기

브라우저에서 콘솔을 열고 다음 코드를 연다. (node 사용가능)

const friends = ["dal", "mark", "lynn", "guy"]

해당 코드를 입력한 뒤 friends 를 입력해보면 배열에 저장된 것이 확인된다.

이제 map() 함수를 사용할 것이다.

map() 함수는 배열의 모든 원소마다 특정 작업을 하는 함수를 적용하고,

그 함수가 반환한 결과를 모아서 배열로 반환해 준다.

 

- map() 함수 사용해서 이름에 하트 추가한 배열 만들기

콘솔에 해당 코드를 입력한다.

map() 함수 첫 번째 인자로 특정 작업을 하는 함수 전달.

friends.map(current => {
  console.log(current);
  return 0;
})

dal mark lynn guy 는 반환값이 아님

아래쪽 [0, 0, 0, 0] 이 friends.map(...) 이 최종으로 반환한 값이다.

 

이름들이 먼저 출력된 다음 배열[0, 0, 0, 0] 이 반환되었다.

여기서 map() 함수의 2가지 특징을 알수 있다.

 

friends.map((current) <---- 각 이름들이 실행 되고

console.log(current); 여기서 current가 출력

return 0;  ----> 여기서 0을 반환. [0, 0, 0, 0]

 

첫 번째 특징은

map() 함수의 인자로 전달한 함수는

배열 friends의 원소를 대상으로 실행

friends에는 4개의 원소가 있으니 함수는 4번 실행.

 

두 번째 특징은

그 함수가 반환한 값이 모여 배열이 되고,

그 배열이 map() 함수의 반환값이 된다.

 

 - map() 함수로 이름에 하트 추가한 배열 만들기

 

1.

friends.map()의 인자로 이름 뒤에 하트를 붙여 주는 함수를 전달하면 된다.

함수의 이름은 아무거나 상관없다. 현재 current인데 friend로 짓는다.

중요한건 인자의 이름이 아니라 인자의 배열에 들어 있는 원소가 1개씩 전달되면서

함수가 반복 실행된다는 거다.

 

 

2.

friend에 하트를 더하면 이름 뒤에 하트가 붙은 이름을 원소로 가지는 배열을 얻을 수 있다.

friends.map(function(friend) {
  return friend + "❤";
})

여기서는 화살표 함수가 아니고 이름 없는 함수를 전달함.

이름 없는 함수의 friend에는 friends 배열의 원소가 하나씩 넘어오고,

그 원소에 하트를 붙여 반환하니까 [ "dal❤", "mark❤", "lynn❤", "guy❤" ] 을 얻을 수 있다.

 

 

- map() 함수로 Food 컴포넌트 많이 만들어 보기

이제 vs코드를 실행한다.

foodLike 배열을 확인하면서 map() 함수가 어떻게 작용할지 생각해보자

 

foodLike.map(...)과 같이 작성하고, 

map() 함수에 전달할 인자에는 dish => <Food ... /> 와 깉이 컴포넌트를 반환하는 함수를 전달하면 된다.

dish에는 배열에 있는 원소인 객체 {name: '...', image: '...'} 하나씩 넘어온다.

이것을 dish.name, dish.image 와 같은 방법으로 컴포넌트에 전달하면 된다.

 

1.

map() 함수를 foodLike 배열에 적용해서 코드 작성.

<h1>Hello</h1>은 삭제하고, {foodLike.map(...)} 을 추가하면 된다.

Food 컴포넌트에서 받는 인자를 { name } 로 수정한다.

 

import React from 'react';

function Food({ name }) {
  return <h1>I like {name}</h1>;
}

const foodLike = [ (생략...) ];

function App() {
  return (
    <div>
      {foodLike.map(dish => (<Food name={dish.name} />))}
    </div>
  );
}

export default App;
  • dish에 foodLike의 원소가 하나씩 넘어간다.
  • 그 값을 name props에 전달한 것
  • 원소가 { name: '...', image: '...' } 이러한 객체 형태이므로
  • Food 컴포넌트에 dish.name과 같이 음식 이름을 name props로 넘겨준 것이다.
  • 즉, map() 함수는 [<Food name={...} />, ...] 와 같이 Food 컴포넌트 원소 5개를 가진 배열을 반환한다.
  • 그 결과 음식 이름 5개가 화면에 표시.

 

 

2. Food 컴포넌브에 음식 이미지 출력하기

Food 컴포넌트에 picture props를 추가하자.

picture props에는 dish.image를 전달한다.

import React from 'react';

function Food({ name }) {
  return <h1>I like {name}</h1>;
}

const foodLike = [ (생략...) ];

function App() {
  return (
    <div>
      {foodLike.map(dish => (
      	<Food name={dish.name} picture={dish.image} />
      ))}
    </div>
  );
}

export default App;

코드를 수정하고 저장해도 바뀌는건 없다.

이유는 전달한 picture props를 사용하지 않았기 때문.

 

 

3.

Food 컴포넌트에서 picture props를 받을수 있도록 코드를 수정한다.

그런 다음 h1 엘리먼트를 h2 엘리먼트로 바꾸고 img 엘리먼트를 추가한다.

마지막으로 div 엘리먼트로 h2, img 엘리먼트를 감싸면 된다.

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;

사진과 음식 이름이 나온다면 성공.

이렇듯 map() 함수를 사용하면 배열에 데이터가 몇 개 있든 컴포넌트를 여러 개 출력 가능.

 

※ 만약 이미지에 alt-text 넣어달라는 컴파일 오류가 뜰시

 

아래와 같은 코드를 추가 해준다.

 


중요한 부분이니 몇번 더 연습할것.

 

 

 

 

 

 

반응형

댓글