[React] ReactJS로 영화 웹 서비스 만들기 (3)

Lpla

·

2021. 2. 9. 22:14

반응형

ReactJS로 영화 웹 서비스 만들기 (1)

ReactJS로 영화 웹 서비스 만들기 (2)

ReactJS로 영화 웹 서비스 만들기 (4)

ReactJS로 영화 웹 서비스 만들기 (5)

ReactJS로 영화 웹 서비스 만들기 (6)

ReactJS로 영화 웹 서비스 만들기 (7)

 


#2 JSX & PROPS

컴포넌트(component)

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

 

app.js

function App() {
  return (
    <div className="App">
      안녕하세요.
    </div>
  );
}

export default App;
  • <App /> 은 컴포넌트(component)이다.
  • 컴포넌트는 html을 반환하는 함수다.
  • javscript와 html 사이의 이러한 조합을 JSX라고 한다.
  • 이 jsx라는 것은 React에서만 쓰이는 유일한 개념이다.

 

컴포넌트 만들기

  • src 폴더 안에 원하는 이름의 js파일을 생성한다. (나는 Latte.js로 만들었다.)
  • 컴포넌트를 생성할 때마다 상단에 import React from "react"; 를 작성해야 하지만 현재 기준으로 자동인식되기 때문에 하지 않아도 된다.

Latte.js

function Latte() {
  return <h1>라떼는 맛있다!</h1>;
}

export default Latte;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import Latte from './Latte';

ReactDOM.render(
  <React.StrictMode>
    <App /><Latte />
  </React.StrictMode>,
  document.getElementById('root')
);

  • 강의에서는 <App /> 과 <Latte /> 를 붙여 놓을 경우 에러가 발생했지만 지금은 그 오류가 나오지 않는다.
  • 그 이유는 <React.StrictMode> 때문인데 이것을 지우면 똑같은 에러가 발생한다.
  • 에러가 발생한다면 App.js 안에 <Latte /> 를 호출하면 된다.

 

컴포넌트에 정보 보내기

  • 방금 생성한 Latte.js 를 삭제하고 코드를 수정한다.

 

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

 

App.js

function App() {
  return (
    <div className="App">
      <h1>안녕하세요!</h1>
      <Latte />
    </div>
  );
}

function Latte() {
  return <h2>라떼는 맛있다!</h2>
}

export default App;

 

  • jsx로 Latte 함수를 만들어 <Latte /> 컴포넌트에 정보를 보낸 것이다.
  • function Latte() {...}가 없을 경우 에러가 발생한다.

 

Prop (Properties)

 

App.js

function Coffee() {
  return <h2>라떼는 맛있다!</h2>
}

function App() {
  return (
    <div className="App">
      <h1>안녕하세요!</h1>
      <Coffee fav="Latte"/>
    </div>
  );
}

export default App;
  • Coffee 컴포넌트(Component)에 fav라는 프로퍼티(Property)를 Latte 라는 값(Value)으로 주었다.

 

<Coffee fav="Latte" hate="Espresso" soso="GreenTee"/>
  • 당연히 여러 개의 Props를 만들 수 있고 콘솔로그로 호출하면 인자를 확인할 수 있다.
function Coffee(props) {
  console.log(props);
  return <h2>라떼는 맛있다!</h2>
}

 

function Coffee(props) {
  console.log(props);
  return (
    <div>
      <h2>{props.fav}는 맛있다!</h2>
      <h2>{props.hate}는 맛없다!</h2>
      <h2>{props.soso}는 평범하다.</h2>
    </div>
  );
}

 

function Coffee({fav}) {
  return (
    <div>
      <h2>{fav}는 맛있다!</h2>
    </div>
  );
}

function App() {
  return (
    <div className="App">
      <h1>안녕하세요!</h1>
      <Coffee fav="Latte" />
      <Coffee fav="Espresso" />
      <Coffee fav="GreenTee" />
    </div>
  );
}

export default App;

  • 이런 식으로 활용 가능하다. (여기까지도 쉬운 것 같다.)

 

Map을 이용한 효율적인 컴포넌트 생성

  • 위 방법은 <Coffe fav=""> 를 계속 생성해야 하는 번거로운 작업이 필요하다.
  • 우리는 데이터를 동적으로 생성하는 법을 알아야 한다.
  • 먼저 필요한 데이터가 미리 존재한다고 가정하기 위해서 사전 작업이 필요하다.
const CoffeeList = [
  {
    name : "Latte",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110569]_20150813221315652.jpg"
  },
  {
    name : "Americano",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110563]_20150813222100303.jpg"
  },
  {
    name : "Cappuccino",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110601]_20150803101742023.jpg"
  },
  {
    name : "Caffe Mocha",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[46]_20150803105115048.jpg"
  },
  {
    name : "Espresso",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[20]_20150813221922951.jpg"
  }
]

// 이미지 출처 : 스타벅스

 

function Coffee({fav, picture}) {
  return (
    <div>
      <h2>{fav}는 맛있다!</h2>
      <img src={picture} />
    </div>
  );
}

function App() {
  return (
    <div className="App">
      {CoffeeList.map(menu => <Coffee fav={menu.name} picture={menu.image} />)}
    </div>
  );
}
  • JSX에서 중괄호를 사용하여 자바스크립트를 사용할 수 있다. 중괄호가 없다면 일반 텍스트.
  • map과 화살표함수를 사용하여 fav와 picture이라는 프로퍼티에 각각 menu.name과 menu.image 값을 주었다.

 

다른 방법도 있다.

  • 위 방법 말고 아래처럼 코드를 짤 수도 있다.
  • 가독성은 좀 더 좋을 지 몰라도 함수를 하나 더 만들어야 하는 단점이 있다.
function Coffee({fav, picture}) {
  return (
    <div>
      <h2>{fav}는 맛있다!</h2>
      <img src={picture} />
    </div>
  );
}

function renderCoffee(list) {
  return <Coffee fav={list.name} picture={list.image} />
}
function App() {
  return <div>{CoffeeList.map(renderCoffee)}</div>
}

 

 

key prop 에러

  • 방금 코드는 이런 방법도 있다는 설명을 위한 용도였고 다시 이전의 코드로 돌아간다.
  • Console을 보면 에러가 하나 있다.
  • Each child in a list should have a unique "key" prop.
  • 즉 각각의 고유한 Key를 만들어줘야 한다.
function Coffee({fav, picture}) {
  return (
    <div>
      <h2>{fav}는 맛있다!</h2>
      <img src={picture} />
    </div>
  );
}

const CoffeeList = [
  {
    id:1,
    name : "Latte",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110569]_20150813221315652.jpg"
  },
  {
    id:2,
    name : "Americano",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110563]_20150813222100303.jpg"
  },
  {
    id:3,
    name : "Cappuccino",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110601]_20150803101742023.jpg"
  },
  {
    id:4,
    name : "Caffe Mocha",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[46]_20150803105115048.jpg"
  },
  {
    id:5,
    name : "Espresso",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[20]_20150813221922951.jpg"
  }
]

id라는 key를 만들었지만 함수에서 인자로 사용하고 있지 않기 때문에 실제로 출력되진 않는다.

 

 

alt 생성

  • 코드를 자세히 보면 물결무늬로 경고가 뜨고 있다. 커서를 올려 확인해보면 alt 요소가 없기 때문이다.
  • alt 요소는 일반인들은 거의 사용하지 않는다. 엑박이 떴을 때나 볼 수 있지 그 외에는 마주할 일이 없다.
  • 시각장애인들에게 이미지를 설명하는 용도로 쓰이는데 웹에서는 사용하길 권장하고 있다.
function Coffee({fav, picture}) {
  return (
    <div>
      <h2>{fav}는 맛있다!</h2>
      <img src={picture} alt={fav} />
    </div>
  );
}
  • 간단히 alt를 작성하면 경고표시는 사라진다.

 

prop 점검하기(prop-types)

  • 현재 갖고 있지 않은 prop을 출력할 경우 당연히 에러가 발생한다.
  • 우리는 사람이기 때문에 실수를 하고 이를 방지할 수 있는 무언가가 필요하다.
  • prop-types는 내가 전달받은 props가 내가 원하는 타입인지 확인할 때 쓰인다.
  • npm i prop-types
  • package.json에 보면 설치된 것을 확인할 수 있다.

 

import propTypes from "prop-types"

Coffee.propTypes = {
  fav: propTypes.string.isRequired,
  picture: propTypes.string.isRequired
}
  • 상단에 설치한 prop-types를 import하고 fav: propTypes.string.isRequired 로 string인지 타입을 확인할 수 있다.
  • 이때 대소문자를 잘 지키도록 하자. 이 부분에서 틀려 오류가 발생하는 사람들이 많다.

  • 이런 오류가 발생하면 타입이 잘못된 것이고 콘솔이 뜨지 않는다면 정상적이다.

 

전체 코드 (App.js)

import propTypes from "prop-types"

Coffee.propTypes = {
  fav: propTypes.string.isRequired,
  picture: propTypes.string.isRequired,
  rating: propTypes.string.isRequired,
}

const CoffeeList = [
  {
    id:1,
    name : "Latte",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110569]_20150813221315652.jpg",
    rating: 5
  },
  {
    id:2,
    name : "Americano",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110563]_20150813222100303.jpg",
    rating: 4.2
  },
  {
    id:3,
    name : "Cappuccino",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[110601]_20150803101742023.jpg",
    rating: 3
  },
  {
    id:4,
    name : "Caffe Mocha",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[46]_20150803105115048.jpg",
    rating: 4.7
  },
  {
    id:5,
    name : "Espresso",
    image : "https://image.istarbucks.co.kr/upload/store/skuimg/2015/08/[20]_20150813221922951.jpg",
    rating: 1
  }
]

function App() {
  return (
    <div className="App">
      {CoffeeList.map(menu => <Coffee key={menu.id} fav={menu.name} picture={menu.image} rating={menu.rating}/>)}
    </div>
  );
}

export default App;

 

반응형