No.1 ReactJS로 영화 웹 서비스 만들기

😓 리액트를 너무 손 놨던것 같아서 노마드코더 영상을 보면서 다시 차근차근 공부해보려한다.

Creating your first React Component

JSX는 react의 유일한 커스텀 개념이라고 생각하면된다. 따라서 vue, angular를 배울땐 JSX를 쓸 이유가 사라지는것이다.

component 만들기

src안에 자신이 좋아하는 파일명의 component를 만들어보자(니콜라스는 potato.js로 만들었다.)

component를 작성할 때 마다 import React from 'react';를 써주는것을 잊지말자! 만약 쓰지 않는다면 react는 jsx가 있는 component를 사용하는 것을 알 수 없기 때문이다.

import React from 'react';

//함수명은 대문자로 시작해주자
function Potato(){
	return(
    	<h3> Hello Potato! </h3>
    )
}

//export를 사용해 potato를 사용한다는것을 알려야한다.
export default Potato;

만들어진 potato를 어떻게 사용할까? index.js 파일을 보면 App을 사용할 때 다음과 같은 코드를 사용하고 있음을 알 수 있다.

import App from './App';

그렇다면 아래와 같은 코드를 사용해 넣을수 있는것일까?

//index.js 파일에서 넣어보자
import Potato from './Potato';

ReactDOM.render(
  <React.StrictMode>
    <App /><Potato /> {/* Patato를 App옆에 넣었다.*/}
  </React.StrictMode>,
  document.getElementById('root')
);

작동하지 않는 이뉴는 하나의 component만을 렌더링 해야하기 때문이고, 그 component는 현재 App이기 때문에 App 안에 넣어야 작동하는것을 볼 수 있다.
(해당 영상에서는 작동하지 않지만 21.08.08일인 지금은 2개의 컴포넌트도 렌더링이 된다.)

💡 "./파일명"을 해주는 이유
현재 App.js와 Potato.js는 src라는 같은 directory에 있기 때문에 "./"로 알려주는것

이제 아래와 같은 코드로 다시 만들어보자

//App.js에 Potato.js를 넣는것

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

react 서버로 가서 확인해보니 App.js에 써있는 'Hello!'와 Potato.js에 있는'Hello Potato!'가 나타나는것을 확인 할 수 있다.(어떻게 확인하는지 모르겠다면 제 블로그의 개념정리(react)를 봐주세요 🥺)

개발자 툴로 소스코드를 보면 react가 component를 가져와서 브라우저가 이해할 수 있는 평범한 html로 바꾼것을 확인 할 수 있다.(😁 이 방법 또한 이해하기 어렵다면 제 블로그를 참고해주세요)


자식 component에서 부모에게 정보 전달하기

이제 Potato를 지우고 App.js에서 작업을 하자!(계속 파일을 만들고 이동하면서 하고 싶지않기 때문에)

//다시 Potato를 만들고 싶다면 App.js파일 안에 아래와 같이 만들 수 있다.
function Potato() {
  return (
    <div>
      <h3>Potato!!🤩</h3>
    </div>
  )
}

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

react는 재사용 가능한 component를 만들 수 있다는 장점이 있는데, 이 말은 component를 계속 반복 사용할 수 있다는 뜻이다. Potato를 Movie로 바꿔서 생각해보자. 20편의 영화 리스트를 가지고 있을 때, 를 20개씩 수동으로 만들면 비효율적이기도 하고 react를 사용 해야 할 이유도 없을 것이다. 따라서 수많은 영화 리스트를 동적으로 처리하기 위해선 component에서 자식 component로 정보를 보내는 방법을 알아야 한다.

이제 Potato대신 Food라고 바꾼뒤 application에서 food로 정보를 보내고 그 다음 food에서 받아온 정보를 어떻게 사용할지 알아보자

function Food() {
  return (
    <div>
      <h3>Food!!🤩</h3>
    </div>
  )
}

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Food fav="kimchi"/> {/*html과 비슷한 방식인것을 볼 수 있다.*/}
    </div>
  );
}

food component에 정보를 보내는 방법은 위와 같은 코드로 만들수 있다. 현재는 정보는 보냈지만 정보를 사용하지 않았기 때문에 새로고침을 해도 변화가 없는것을 볼 수 있다. 하지만 우리가 한 일은 react의 첫 개념 중 하나인데 그것은 food component에 kimchi라는 value로 prop(property) name을 줬다는 것이다.

props(property의 축약어)를 어떻게 사용할까? react는 우리가 전달한 props를 가져가는 일을 할 수 있다. 따라서 우리는 부모에서 자식으로 전달 할 때 원하는 만큼 props를 보낼 수 있다.

예를 들어 food component로 정보를 보내려 한다면 react는 모든 props를 가져올것이고, food function component의 arg로 그것들을 넣을것이다.

function Food(props) {
  console.log(props)
  return (
    <div>
      <h3>Food!!🤩</h3>
    </div>
  )
}

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Food fav = "kimchi" someting = {['Jetom', 1, 2, 3, 4]}/>
    </div>
  );
}

실제로 console.log로 확인하니 props가 찍힌것을 볼 수있다. props는 obj이므로 아래와 같은 코드로 접근할 수 있다.

//fav만 남기고 나머지 props는 지웠다.
function Food(props) {
  console.log(props.fav)
  return (
    <div>
      <h3>Food!!🤩</h3>
    </div>
  )
}

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Food fav = "kimchi"/>
    </div>
  );
}


(작고 소중한 kimchi가 찍혔다.)

이제 props의 내부 값인 fav를 꺼내려한다면 아래와 같은 코드를 사용해보자

//p
function Food({fav}) {
  //props.fav와 같은 방법이다.
  return (
    <div>
      <h3>{fav}!!🤩</h3> {/*이곳에 fav를 넣어준다면 food에서 kimchi가 될것이다.*/}
    </div>
  )
}

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Food fav = "kimchi"/>
    </div>
  );
}

이제 다른 component를 만드려면 아래와 같이 작성할 수 있다. 이것이 (jsx와 props로 component를 재사용할 수 있는 방법이다.)

function Food({ fav }) {
  return (
    <div>
      <h3>{fav}!!🤩</h3>
    </div>
  )
}

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Food fav="kimchi 🇰🇷" />
      <Food fav="banana 🍌" />
      <Food fav="strawberry 🍓" />
      <Food fav="meet 🍖" />
    </div>
  );
}

//food의 fav는 하나인데 App에서 만든 compoent에 따라 나타나는것 을 볼 수 있다.


Dynamic Component Generation

우리는 App compoent에 새로운 음식을 추가 할 때마다 복사 & 붙여넣기를 하기때문에 이것은 효율적이지 않았다. 이런 복사 & 붙여넣기를 하는 이유는 처음부터 데이터를 가지고 있지 않았기 때문이다. 따라서 웹사이트의 동적 데이터는 어떤식으로 추가 하는지 지금부터 알아보겠다.

우선 데이터가 이미 API에서 왔다고 가정 해보기 위해선 먼저 함수를 만들고 그 함수명은 foodILike로 불리는 array라고 만들자 (이 foodILike는 food obj의 배열이 될것이다.)

function Food({ fav }) {
  return (
    <div>
      <h3>{fav}!!🤩</h3>
    </div>
  )
}

//arr안에 obj로 음식과 이미지를 담았다.
const foodILike = [
    {
    name: 'kimchi 🇰🇷',
    image: 'http://08food.com/web/product/big/201801/33_shop1_243196.jpg'
  },
  {
    name: 'banana 🍌',
    image: 'https://src.hidoc.co.kr/image/lib/2020/12/11/1607668328502_0.jpg'
  },
  {
    name: 'strawberry 🍓',
    image: 'http://www.foodnmed.com/news/photo/201802/12728_2384_0900.jpg'
  },
  {
    name: 'meet 🍖',
    image: 'http://www.foodnmed.com/news/photo/201812/17332_3510_1310.jpg'
  }
]

function App() {
  return (
    <div>
      <h1>Hello</h1>
      {/*이곳에 list를 담을 예정*/}
    </div>
  );
}

이제 어떻게 하면 자동적으로 array를 가져와서 렌더링을 할까? 정답은 javascript의 map을 이용하는것이다. map을 간단하게 살펴보자

📝 map()

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map

const dog = ['jetom', 'rari'];

//element에 return 0을 해주면 배열에 차례대로 0이 담기는것을 볼 수 있다.
dog.map(item => {console.log(item); return 0});

//arrow function을 사용하지 않을땐 다음과 같이 나타낸다.
dog.map(function(item){console.log(item); return 0});

map을 가지고 이번엔 dog element에 '🐶'를 추가해보겠다.

const dog = ['jetom', 'rari'];

//꼭 item이라 붙힐 필요없다.
dog.map(item => `${item}  🐶`);

map에 대해 알았으니 다시 react로 돌아가서 원하는 결과를 출력하자

//name이 필요해서 name으로 바꿔줬다.
function Food({ name }) {
  return (
    <div>
      <h3>{name}!!🤩</h3>
    </div>
  )
}

//foodILike 코드 생략

//현재 eat는 obj이며, obj 값을 가져오는 방식을 통해서 다음과 같이 입력하면된다.
function App() {
  return (
    <div>
      {/* object를 가져오는게 이해가 안간다면 제 블로그에서 객체를 봐주세요^^ㅎㅎ*/}
      {foodILike.map(eat => <Food name ={eat.name}}/> )}
    </div>
  );
}

위의 코드대로 만들었다면 복사 + 붙여넣기를 일일이 했던 방식과 같은 결과를 확인 할 수 있다.

같은 방법으로 img(image)를 가져오려면 아래의 코드와 같이 입력하면된다.

//name 다음으로 picture를 props로 받아줬다.
function Food({ name, picture }) {
  return (
    <div>
      <div>
        {/*h1에서 코드를 수정했다.*/}
        <h2>{name}!!🤩</h2>
        <img src={picture}/>
      </div>
    </div>
  )
}

function App() {
  return (
    <div>
      {foodILike.map(eat => <Food name ={eat.name}, picture = {eat.image}/> )}
    </div>
  );
}

좋은 웹페이지 즐겨찾기