0 Introduction

0.0 Introduction

- js 2019 / js 베이직 / 리액트 js 입문수업

리액트를 왜 좋아하는가
활용하는 방법
어플리케이션 만드는 방법
API에서 데이터를 가져오는 방법
앱이 다이내믹 데이터를 출력하는 방법
리액트 앱을 배포하는 방법

- 수업을 마치면

  • 업데이튼 된 리액트 JS 지시을 갖게되고, 최신 리액트 앱을 만들 수 있음

0.1 Requirements

- 수업을 듣기 위한 필요조건

  1. node.js 설치 ( nodejs.org 에서 다운 / 10,12버전 / 10이 안정적 )
node -v
  1. npm 설치
npm -v
  1. npx 설치 (node js, npm 설치 되어있는지 확인하고 실행하기)
npm install npx -g
npx -v
  1. Visual Studio Code (VSC) 필요
  2. git 필요 git -v
git --version

0.2 Theory Requirements

- 리액트 JS를 배우기 전에 무엇을 알아야 할까?

  • HTML
  • CSS
  • 바닐라 JS
  • node js .package.json

0.3 Why React

-왜 리액트냐

  • 페이스북이 만듬
  • 요즘 회사들은 거의 리액트를 사용, 디폴트
  • 에어비앤비, npm, 넷플릭스, 스포티파이, 슬랙 등등등..
  • 리액트 라이브러리
  • 사용자가 늘고있음, 커뮤니티 잘되어 있음.
  • 자바스크립트로 이루어져 있음

1 Setup

1.0 Creating your first React App

- React를 어떻게 시작할까?

create-react-app

npx create-react-app 폴더이름
npx create-react-app movie_app_2019

code movie_app_2019
cd movie_app_2019 // movie_app_2019 폴더 경로 안으로 접근 (변경)
npm start //실행

1.1 Creating a Github Repository

git init
  • 기존 저장소를 다시 초기화 하라는 메시지를 주거나 또는 저장소를 초기화 하라고 뜸
  1. https://github.com/new/ 접속

    • Repository name : movie_app_2019 작성
    • Description (optional) : React JS Fundamentals Course (2019 Update!) 작성
    • Public 선택 후 Create repository 생성버튼 클릭 저장소생성
  2. 브라우저 url 경로 복사 https://github.com/sunmi8873/movie_app_2019

 git remote add origin https://github.com/sunmi8873/movie_app_2019
 git add.
 git commit -m "first React App"
 git push origin master
 git init
 remote
 branch checkout
 git add ./ 
 git commit -m '코멘트'
 git push origin psm

1.2 How does React work?

  • 리액트가 동작하는 방법
  • react는 소스코드를 처음부터 HTML을 넣지 않고, HTML에서 HTML을 추가하거나 제거하는 법을 알고 있어.
    그래서 application 로드할때 빈 HTML을 로드하고 다음에 react가 HTML을 밀어 넣게돼
  • virtual DOM (virtual document object model)
    존재하지 않아, 리액트가 그걸 만들어내고
  • react가 빠른 이유 : virtual 이고 , 존재하지 않음

2 JSX & Props

2.0 Creating your first React Component

  • npm start 를 실행하고 그대로 둔다 ( 서버를 찾을수 없을때)

- JSX

  • react 는 component와 함께 동작함
  • componont : HTML을 반환하는 함수, 대문자로 시작해야되고 component로 정보를 보낼 수 있다.
  • jsx : react에서 나온 매우 custom한 유일한 개념
  • jsx : HTML + JavsScript ( javascript안의 HTML이다. )

리액트 공식문서

  • const element = <h1>Hello, world!</h1>;
    • JSX : 자바스크립트의 문법 확장
  • 왜 JSX인가?
    • React는 렌더링 로직이 다른 UI 로직과 본질적으로 결합되어 있다는 사실, 이벤트 처리 방법, 시간에 따른 상태 변경 방법 및 데이터 표시 준비 방법을 포함
  • JSX에 표현식 포함하기
  • JSX에 표현식 포함하기
  • JSX 또한 표현식이다
  • JSX 속성 정의
  • JSX 자식 정의
  • JSX 인젝션 공격 예방
  • JSX 객체 표현

- componont를 만드는 법

  • react application은 한번의 하나의 component만을 rendering 할 수 있다.
/* Potato.js */

import React from "react";

function Potato() {
    return <h3>I love potato</h3>;
}

export default Potato;
/* index.js */

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

ReactDOM.render(<App />, document.getElementByID("potato"));

리액트 공식문서

  • component
    컴포넌트를 사용하여 UI를 독립적이고 재사용 가능한 부분으로 분리하고 각 부분을 독립적으로 생각할 수 있습니다.
  • 함수형 컴포넌트
    function Welcome(props) {
       return <h1>Hello, {props.name}</h1>;
    }
  • 클래스형 컴포넌트
    class Welcome extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }

2.1 Reusable Components with JSX + Props

  • component 에 정보를 보낼 수 있다.
  • 재사용가능한 component를 만들 수 있다. 반복사용 가능
  • props
  • father 가 children에게 data를 어떻게 보낼가? app이 어떻게 food에게 props를 사용에서 data를 보낼까?
  • props는 어디로 갈까? argument로 가, food의 첫번째 argument로 간다.
import React from "react";
import Potato from "./Potato";

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

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Potato />
      <Food favourite="kimchi" />
      <Food favourite="ramen" />
      <Food favourite="samgiopsal" />
      <Food favourite="chukumi" />
    </div>
  );
}

리액트 공식문서

  • Props는 읽기전용
  • 컴포넌트를 함수나 클래스 중 어떤 걸로 선언했 건, props를 수정할 수 없습니다.
  • 모든 React 컴포넌트는 props와 관련한 동작을 할 때 순수 함수처럼 동작해야한다.

2.2 Dynamic Component Generation

- 웹사이트에 동적 데이터를 추가하는 방법

import React from "react";

function Food({ favourite }) {
  return <h1>I like {favourite}</h1>;
function Food({ name, picture }) {
  return (
    <div>
      <h2>I like {name}</h2>
      <img src={picture} />
    </div>
  );
}

const foodILike = [
  {
    name: "Kimchi",
    image:
      "http://aeriskitchen.com/wp-content/uploads/2008/09/kimchi_bokkeumbap_02-.jpg"
  },
  {
    name: "Samgyeopsal",
    image:
      "https://3.bp.blogspot.com/-hKwIBxIVcQw/WfsewX3fhJI/AAAAAAAAALk/yHxnxFXcfx4ZKSfHS_RQNKjw3bAC03AnACLcBGAs/s400/DSC07624.jpg"
  },
  {
    name: "Bibimbap",
    image:
      "http://cdn-image.myrecipes.com/sites/default/files/styles/4_3_horizontal_-_1200x900/public/image/recipes/ck/12/03/bibimbop-ck-x.jpg?itok=RoXlp6Xb"
  },
  {
    name: "Doncasu",
    image:
      "https://s3-media3.fl.yelpcdn.com/bphoto/7F9eTTQ_yxaWIRytAu5feA/ls.jpg"
  },
  {
    name: "Kimbap",
    image:
      "http://cdn2.koreanbapsang.com/wp-content/uploads/2012/05/DSC_1238r-e1454170512295.jpg"
  }
];

function App() {
  return (
    <div>
      <h1>Hello</h1>
      <Food favourite="kimchi" />
      <Food favourite="ramen" />
      <Food favourite="samgiopsal" />
      <Food favourite="chukumi" />
      {foodILike.map(dish => (
        <Food name={dish.name} picture={dish.image} />
      ))}
    </div>
  );
}

2.3 .map Recap

import React from "react";

function Food({ name, picture }) {
  return (
    <div>
      <h2>I like {name}</h2>
      <img src={picture} />
    </div>
  );
}

const foodILike = [
  {
    id: 1,
    name: "Kimchi",
    image:
      "http://aeriskitchen.com/wp-content/uploads/2008/09/kimchi_bokkeumbap_02-.jpg"
  },
  {
    id: 2,
    name: "Samgyeopsal",
    image:
      "https://3.bp.blogspot.com/-hKwIBxIVcQw/WfsewX3fhJI/AAAAAAAAALk/yHxnxFXcfx4ZKSfHS_RQNKjw3bAC03AnACLcBGAs/s400/DSC07624.jpg"
  },
  {
    id: 3,
    name: "Bibimbap",
    image:
      "http://cdn-image.myrecipes.com/sites/default/files/styles/4_3_horizontal_-_1200x900/public/image/recipes/ck/12/03/bibimbop-ck-x.jpg?itok=RoXlp6Xb"
  },
  {
    id: 4,
    name: "Doncasu",
    image:
      "https://s3-media3.fl.yelpcdn.com/bphoto/7F9eTTQ_yxaWIRytAu5feA/ls.jpg"
  },
  {
    id: 5,
    name: "Kimbap",
    image:
      "http://cdn2.koreanbapsang.com/wp-content/uploads/2012/05/DSC_1238r-e1454170512295.jpg"
  }
];

function Food({ name, picture }) {
  return (
    <div>
      <h2>I like {name}</h2>
      <img src={picture} alt={name} />
    </div>
  );
}

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

2.4 Protection with PropTypes

  • father component로 부터 전달받은 props가 우리가 예상한 props인지를 점검할 필요가 있다.
  • prop-types : 내가 전달받은 props가 내가 원하는 props인지를 확인
npm i prop-types
"version": "0.1.0",
  "private": true,
  "dependencies": {
    "prop-types": "^15.7.2",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.1"


import React from "react";
import PropTypes from "prop-types";

const foodILike = [
  {
@@ -11,42 +12,58 @@ const foodILike = [
    id: 2,
    name: "Samgyeopsal",
    image:
      "https://3.bp.blogspot.com/-hKwIBxIVcQw/WfsewX3fhJI/AAAAAAAAALk/yHxnxFXcfx4ZKSfHS_RQNKjw3bAC03AnACLcBGAs/s400/DSC07624.jpg"
      "https://3.bp.blogspot.com/-hKwIBxIVcQw/WfsewX3fhJI/AAAAAAAAALk/yHxnxFXcfx4ZKSfHS_RQNKjw3bAC03AnACLcBGAs/s400/DSC07624.jpg",
    rating: 4.9
  },
  {
    id: 3,
    name: "Bibimbap",
    image:
      "http://cdn-image.myrecipes.com/sites/default/files/styles/4_3_horizontal_-_1200x900/public/image/recipes/ck/12/03/bibimbop-ck-x.jpg?itok=RoXlp6Xb"
      "http://cdn-image.myrecipes.com/sites/default/files/styles/4_3_horizontal_-_1200x900/public/image/recipes/ck/12/03/bibimbop-ck-x.jpg?itok=RoXlp6Xb",
    rating: 4.8
  },
  {
    id: 4,
    name: "Doncasu",
    image:
      "https://s3-media3.fl.yelpcdn.com/bphoto/7F9eTTQ_yxaWIRytAu5feA/ls.jpg"
      "https://s3-media3.fl.yelpcdn.com/bphoto/7F9eTTQ_yxaWIRytAu5feA/ls.jpg",
    rating: 5.5
  },
  {
    id: 5,
    name: "Kimbap",
    image:
      "http://cdn2.koreanbapsang.com/wp-content/uploads/2012/05/DSC_1238r-e1454170512295.jpg"
      "http://cdn2.koreanbapsang.com/wp-content/uploads/2012/05/DSC_1238r-e1454170512295.jpg",
    rating: 4.7
  }
];

function Food({ name, picture }) {
function Food({ name, picture, rating }) {
  return (
    <div>
      <h2>I like {name}</h2>
      <h4>{rating}/5.0</h4>
      <img src={picture} alt={name} />
    </div>
  );
}

Food.propTypes = {
  name: PropTypes.string.isRequired,
  picture: PropTypes.string.isRequired,
  rating: PropTypes.number
};

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