티스토리 뷰

 


1. Axios

(1) Axios란?

-자바스크립트로 비동기 통신을 할 수 있도록 해주는 모듈
 (*자바스크립트에는 기본적으로 비동기 통신을 위한 XHR[XML Http Request]라는 것이 존재)
 (*XHR을 사용하여 ajax 통신하는데 사용하는데 사용 방법이 어려움.)
-jQeury를 사용하면 ajax 통신을 쉽게 할 수 있음. $.ajax, $.get, $.post
-frontend 개발 시 jQuery의 각종 문제점 때문에 jQuery를 사용하지 않게 되면서
 비동기 통신을 쉽게 할 수 있는 방법이 필요 → ★ Axios ★

-비동기 함수인 promise 기반으로 실행되기 때문에 then, catch 등 사용

→ React 및 Vue.js에서는 Axios 모듈을 사용하여 비동기 통신을 구현

 

(2) Axios 설치

-VSCODE TERMINAL(터미널)에서 cmd 상태일 것!!

>>yarn add axios

>> 설치 완료시

success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ axios@0.26.1
info All dependencies
└─ axios@0.26.1
Done in 14.56s.

 

*npm 검색해서 axios 검색 → 홈페이지 접속하면 사용방법 등을 볼 수 있음.

(3) CommonJS
-ES5 버전에서 사용하던 node.js 로딩하는 방법. / ES6부터는 import 사용.
-이전 버전에서
 const axios = require('axios').default; 사용하던 방법

 

 

(4) Chrome postman

-앱 추가하면 별도의 설치 필요없이 사용 가능. (앱 추가할 때만 구글 로그인이 필요함)

https://yts.mx/api/v2/list_movies.json

▶  크롬에서 데이터가 막 나열되던 것이 정렬되어 보여지는 것을 확인할 수 있음.

 

 

(4-2) 서버 통신시 상태 코드

-200 : 성공

-300 : redirect

-400대 : 에러 / 접속 불가

-500대 : 서버 내부 오류

 

(4-3) Cookies / Session

 

(4-4) Headers : 정보들...

access-control-allow-origin *
age 0
alt-svc h3=":443"; ma=86400, h3-29=":443"; ma=86400
cache-control max-age=3600, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
cf-cache-status DYNAMIC
cf-ray 6ffa4a873daf12f2-ICN
content-encoding br
content-type application/json; charset=utf-8
date Fri, 22 Apr 2022 00:37:30 GMT
expect-ct max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
expires Fri, 22 Apr 2022 01:37:30 GMT
nel {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
pragma no-cache
report-to {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=M60YFMRybceXHguesl3fhFgC5ki%2BCSMPTAOudRjDvUxPYd5MxJlZ68VxoUk%2FBJ5rjoaaoeCRovdO5%2FBBJJp8gacuoXf89JvgMFFsDznhRy2MpuTPrqZhJQ%3D%3D"}],"group":"cf-nel","max_age":604800}
server cloudflare
strict-transport-security max-age=0; includeSubDomains; preload
via 1.1 varnish (Varnish/5.2)
x-content-type-options nosniff
x-frame-options DENY
x-varnish 459354

 

(5) 노마드 코더 영화 API 사용

(5-1) 노마드 코더 영화 API 깃허브 주소 / ??때문에 악성코드 있을 수 있어서 사용 x

https://github.com/serranoarevalo/yts-proxy

(5-2) 데이터

영화 리스트 https://yts-proxy.now.sh/list_movies.json
영화 상세 정보 https://yts-proxy.now.sh/movie_details.json
특정 영화 상세 정보 https://yts-proxy.now.sh/movie_details.json?movie_id=10

└영화 상세 정보 주소만 입력하면 아무 것도 안 뜸. 특정 아이디를 입력해야 그에 맞는 정보가 뜸.

{
    "status": "ok",
    "status_message": "Query was successful",
    "data": {
        "movie": {
            "id": 10,
            "url": "https://yts.mx/movies/13-2010",
            "imdb_code": "tt0798817",
            "title": "13",
            "title_english": "13",
            "title_long": "13 (2010)",
            "slug": "13-2010",
            "year": 2010,
            "rating": 6,
            "runtime": 91,
            "genres": [
                "Action",
                "Crime",
                "Drama",
                "Thriller"
            ],
            "download_count": 249542,
            "like_count": 284,
            "description_intro": "In Talbot, Ohio, a father's need for surgeries puts the family in a financial bind. His son Vince, an electrician, overhears a man talking about making a fortune in just a day. When the man overdoses on drugs, Vince finds instructions and a cell phone that the man has received and substitutes himself: taking a train to New York and awaiting contact. He has no idea what it's about. He ends up at a remote house where wealthy men bet on who will survive a complicated game of Russian roulette: he's number 13. In flashbacks we meet other contestants, including a man whose brother takes him out of a mental institution in order to compete. Can Vince be the last one standing? —",
            "description_full": "In Talbot, Ohio, a father's need for surgeries puts the family in a financial bind. His son Vince, an electrician, overhears a man talking about making a fortune in just a day. When the man overdoses on drugs, Vince finds instructions and a cell phone that the man has received and substitutes himself: taking a train to New York and awaiting contact. He has no idea what it's about. He ends up at a remote house where wealthy men bet on who will survive a complicated game of Russian roulette: he's number 13. In flashbacks we meet other contestants, including a man whose brother takes him out of a mental institution in order to compete. Can Vince be the last one standing? —",
            "yt_trailer_code": "Y41fFj-P4jI",
            "language": "en",
            "mpa_rating": "R",
            "background_image": "https://yts.mx/assets/images/movies/13_2010/background.jpg",
            "background_image_original": "https://yts.mx/assets/images/movies/13_2010/background.jpg",
            "small_cover_image": "https://yts.mx/assets/images/movies/13_2010/small-cover.jpg",
            "medium_cover_image": "https://yts.mx/assets/images/movies/13_2010/medium-cover.jpg",
            "large_cover_image": "https://yts.mx/assets/images/movies/13_2010/large-cover.jpg",
            "torrents": [
                {
                    "url": "https://yts.mx/torrent/download/BE046ED20B048C4FB86E15838DD69DADB27C5E8A",
                    "hash": "BE046ED20B048C4FB86E15838DD69DADB27C5E8A",
                    "quality": "720p",
                    "type": "bluray",
                    "seeds": 5,
                    "peers": 6,
                    "size": "946.49 MB",
                    "size_bytes": 992466698,
                    "date_uploaded": "2015-10-31 20:46:37",
                    "date_uploaded_unix": 1446320797
                },
                {
                    "url": "https://yts.mx/torrent/download/FEE33A702158CD451220BD4F23FC46AD7BC65C4D",
                    "hash": "FEE33A702158CD451220BD4F23FC46AD7BC65C4D",
                    "quality": "1080p",
                    "type": "bluray",
                    "seeds": 18,
                    "peers": 5,
                    "size": "1.79 GB",
                    "size_bytes": 1921997865,
                    "date_uploaded": "2022-01-19 00:57:56",
                    "date_uploaded_unix": 1642550276
                }
            ],
            "date_uploaded": "2015-10-31 20:46:37",
            "date_uploaded_unix": 1446320797
        }
    },
    "@meta": {
        "server_time": 1650588707,
        "server_timezone": "CET",
        "api_version": 2,
        "execution_time": "0 ms"
    }
}

 


2. Axios 사용

(1) Axios 설치

-VSCODE TERMINAL(터미널)에서 cmd 상태일 것!!

>>yarn add axios

>> 설치 완료시

success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ axios@0.26.1
info All dependencies
└─ axios@0.26.1
Done in 14.56s.

 

(2) axiostest.js

//axios 모듈 불러오기
// import axios from 'axios';
const axios = require('axios').default;  //ES5 방식 사용 ♠

/*axios 사용법
axios.통신방식(서버주소).then(콜백함수).catch(콜백함수)
*/

axios
  .get('https://yts-proxy.now.sh/list_movies.json')
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log(error);
  });

//SyntaxError: Cannot use import statement outside a module
//import 대신 기존 방식(ES5) 사용 ♠

>> 실행하면, VSCODE 콘솔에 찍힘

{
  status: 200,
  statusText: 'OK',
  headers: {
    date: 'Fri, 22 Apr 2022 01:19:31 GMT',
    'content-type': 'application/json; charset=utf-8',
    'transfer-encoding': 'chunked',
    connection: 'close',
    'set-cookie': [ 'PHPSESSID=ok0io21lpviktfd7ueb0pvr4uc; path=/' ],
    expires: 'Fri, 22 Apr 2022 02:19:31 GMT',
    'cache-control': 'max-age=3600, no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
    pragma: 'no-cache',
    'x-varnish': '4991175',
    age: '0',
    via: '1.1 varnish (Varnish/5.2)',
    'accept-ranges': 'bytes',
    'strict-transport-security': 'max-age=0; includeSubDomains; preload',
    'access-control-allow-origin': '*',
    'x-frame-options': 'DENY',
    'x-content-type-options': 'nosniff',
    'cf-cache-status': 'DYNAMIC',
    'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
    'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=CKE%2B3nx6Tw154RVeAuuiRv7F1rmbygCY6%2Fgk7aGOeVdgMzbPANxk5FOz5VLEPaDf4dHBsaPsNK7tWt19aGdtFds43fe8%2FKY8ScoqbtMj2p2QmbTqWm3IQQ%3D%3D"}],"group":"cf-nel","max_age":604800}',
    nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
    server: 'cloudflare',
    'cf-ray': '6ffa8819aac361d0-ICN',
    'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'
  },
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
....

Do it! 클론코딩)  p.143 ~

3. 영화정보 불러오기

-index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

import App7 from './App7';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App7 />
  </React.StrictMode>,
);

reportWebVitals();

-App7.js

일단 기본틀 잡아두기

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = () => {
    const movies = axios.get('https://yts-proxy.now.sh/list_movies.json');
  }

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

-App7.js

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }
  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
  }
}

export default App7;

 

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = () => {
    const movies = axios.get('https://yts-proxy.now.sh/list_movies.json');
  }

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

(2) 데이터 호출 : movies 정보 찍히는 거 알 수 있음.

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = () => {
    const movies = axios.get('https://yts-proxy.now.sh/list_movies.json');
    console.log(movies);
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

>> 웹 콘솔에 찍히는 거 알 수 있음.

 

(3) 데이터 정보 가져오기

(3-1) 원래 방식

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = () => {
    axios.get('https://yts-proxy.now.sh/list_movies.json').then((res) => {
      console.log(res);
    });
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    this.getMovies();
  }
}

export default App7;

(3-2) 정석 방식 : 에러 상황까지 다 설정

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = () => {
    axios
      .get('https://yts-proxy.now.sh/list_movies.json')
      .then((res) => {
        console.log('Scuccess');
        console.log(res);
      })
      .catch((err) => {
        console.log('Error');
        console.log(err);
      });
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    this.getMovies();
  }
}

export default App7;

 

(3-3) 다른 방식 : 최신방식 async / await

비동기 로직을 처리하기 위한 최신 방법. ES2017 버전에 추가된 새로운 비동기 로직 처리 방식  >> 맨 아래에서 실습

async function 함수명() {
    await 비동기 처리 메서드명();
}

└async 키워드는 비동기 방식임을 알려줌. 해당 함수 내에서 비동기 처리가 필요한 메서드가 있음을 알려줌.

└await 비동기 로직이 끝날 때(완료)까지 로직을 실행하지 않고 기다림.

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }
  
//await, async 추가
  getMovies = async () => {
    const movies = await axios.get('https://yts-proxy.now.sh/list_movies.json');
    console.log(movies);
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

>>웹 콘솔

└결과가 2번 뜨는 이유는 componentDidMount()에 넣었기 때문.

-config

-headers

-request : 우리가 요청한 정보

-data : 우리가 봐야 할 것

영화 정보(data)가 2단계에 있어서 바로 데이터를 가져오게 하려면, 아래와 같이 수정.

 

(+) 데이터 정보 가져오기

  getMovies = async () => {
    try {
      const movies = await axios.get('https://yts-proxy.now.sh/list_movies.json');
      console.log('Scuccess');
      // console.log(movies);
      console.log(movies.data.data.movies); //여러 단계 아래에 있는 데이터를 한번에 접근하려고
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

 

>> 데이터 로딩하기 완료

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = async () => {
    try {
      const movies = await axios.get('https://yts-proxy.now.sh/list_movies.json');
      console.log('Scuccess');
      // console.log(movies);
      console.log(movies.data.data.movies);

      //데이터 입력
      this.setState({ movies: movies.data.data.movies, isLoading: false });
      
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

 

(+) 구조 분해 할당으로 데이터 가져오기 - getMovies()

getMovies = async () => {
    try {
//구조 분해 할당 : axios로 가져온 데이터를 변수 data에 넣음.
      var { data } = await axios.get('https://yts-proxy.now.sh/list_movies.json');
       console.log(data); //{status: 'ok' ...}
       var { data } = data;
       console.log(data); //{movie_count: ...}
      const { movies } = data;
      console.log(movies); //바로 데이터

      //데이터 입력
      // this.setState({ movies: movies.data.data.movies, isLoading: false });
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

(+) 구조 분해 할당 간략하게

getMovies = async () => {
    try {
      //구조 분해 할당을 간략하게
      const {data: {data: {movies}}} = await axios.get('https://yts-proxy.now.sh/list_movies.json');
      console.log(movies);

/* prettier에 따른 저장 ↓
      const {
        data: {
          data: { movies },
        },
      } = await axios.get('https://yts-proxy.now.sh/list_movies.json');
      console.log(movies);
*/
      //데이터 입력
      // this.setState({ movies: movies.data.data.movies, isLoading: false });
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

 

4. 영화 앱

-Movie.js_기본 틀

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

function Movie(){
    return <h1></h1>;
}

Movie.propTypes = {

};

export default Movie;

 

(1) 필요한 데이터 정보 가져오기

(1-1) https://yts.mx/api

 

>> 위의 명령어를 사용하여 endpoint 만들어줌. 가져올 데이터의 조건을 위의 양식에 맞춤.

< EndPoint를 Postman >

(1-2) limit : 지정한 값까지 출력

https://yts-proxy.now.sh/list_movies.json?limit=5

 

(2-2) sort_by : 평점 순대로 정렬

https://yts-proxy.now.sh/list_movies.json?sort_by=rating

>> VSCODE : App7.js 에서 적용해보기

영화 데이터를 필요한 만큼만 가져오기

import React from 'react';
import './App.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };

  render() {
    const { isLoading, sec } = this.state;
    return <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>;
  }

  getMovies = async () => {
    try {
      const {
        data: {
          data: { movies },
        },
      } = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=5'); //★ endPoint
      console.log(movies);
 
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

>> 웹 브라우저에서 확인 : 영화 데이터 5개 가져오는 것 확인

 

 

(2)

App7.js

import React from 'react';
import './App.css';
import Movie from './Movie';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    sec: 5,
    isLoading: true,
    movies: [],
  };
  
//추가 수정
  render() {
    const { isLoading, sec } = this.state;
    return (
      <div>
        <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>
        <Movie />
      </div>
    );
  }

  getMovies = async () => {
    try {
      // //구조 분해 할당 : axios로 가져온 데이터를 변수 data에 넣음.
      // var { data } = await axios.get('https://yts-proxy.now.sh/list_movies.json');
      // console.log(data); //{status: 'ok' ...}
      // var { data } = data;
      // console.log(data); //{movie_count: ...}
      // const { movies } = data;
      // console.log(movies); //바로 데이터

      //구조 분해 할당을 간략하게
      const {
        data: {
          data: { movies },
        },
      } = await axios.get('https://yts-proxy.now.sh/list_movies.json?sort_by=rating');
      console.log(movies);
      // const movies = await axios.get('https://yts-proxy.now.sh/list_movies.json');
      // console.log('Scuccess');
      // console.log(movies);
      // console.log(movies.data.data.movies);
      //데이터 입력
      // this.setState({ movies: movies.data.data.movies, isLoading: false });
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };
  // getMovies = () => {
  //   axios
  //     .get('https://yts-proxy.now.sh/list_movies.json')
  //     .then((res) => {
  //       console.log('Scuccess');
  //       console.log(res);
  //     })
  //     .catch((err) => {
  //       console.log('Error');
  //       console.log(err);
  //     });
  // };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

(2-2) Movie.js

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

function Movie({ id, year, title, summary, poster }) {
  return <h1>{title}</h1>;
}

//정보 가져오기 : id, title, rating...
Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
};

export default Movie;

 

>>데이터 아직 안 나옴

더미 데이터 입력해보자 App7.js의 render() 부분에

  render() {
    const { isLoading, sec } = this.state;
    return (
      <div>
        <div>{isLoading ? `Loading... ${sec}` : 'We are ready'}</div>
        <Movie id="1" year="2022" title="TEST" summary="summary TEST" poster="img" />
      </div>
    );
  }

>> 웹브라우저 -> 검사 -> component

 

(3) Map 활용해서?

-App7.js

import React from 'react';
import './App.css';
import Movie from './Movie';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    isLoading: true,
    movies: [],
  };
  render() {
    const { isLoading, movies } = this.state;
    return (
      <div>
        <div>
          {isLoading
            ? `Loading...`
            : movies.map((movie) => {
                // console.log(movie);
                return (
                  <Movie
                    key={movie.id}
                    id={movie.id}
                    year={movie.year}
                    title={movie.title}
                    summary={movie.summary}
                    poster={movie.medium_cover_image}
                  />
                );
              })}
        </div>
      </div>
    );
  }

  getMovies = async () => {
    try {
      //구조 분해 할당을 간략하게
      const {
        data: {
          data: { movies },
        },
      } = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=5');
      this.setState({ movies: movies, isLoading: false }); //★
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

>> 결과 실행

endpoint로 지정한 영화정보 5개를 가져와 출력. 

제목(title)만 뜨는 이유는 Movie.js에서 출력을 title만 지정해서

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

function Movie({ id, year, title, summary, poster }) {
  return <h1>{title}</h1>; //★★
}

//정보 가져오기 : id, title, rating...
Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
};

export default Movie;

 

 

(4) 보여지는 부분 수정?

render()안에 시멘틱 태그들로 수정? 삼항 연산자 부분도 수정

import React from 'react';
import Movie from './Movie';
import './App7.css';
const axios = require('axios').default;

class App7 extends React.Component {
  state = {
    isLoading: true,
    movies: [],
  };
  render() {
    const { isLoading, movies } = this.state;
    return (
      <section className="container">
        {isLoading ? (
          <div className="loader">
            <span className="loader-text">Loading...</span>
          </div>
        ) : (
          <div className="movies">
            {movies.map((movie) => {
              return (
                <Movie
                  key={movie.id}
                  // id={movie.id}
                  year={movie.year}
                  title={movie.title}
                  summary={movie.summary}
                  poster={movie.medium_cover_image}
                />
              );
            })}
          </div>
        )}
      </section>
    );
  }

  getMovies = async () => {
    try {
      //구조 분해 할당을 간략하게
      const {
        data: {
          data: { movies },
        },
      } = await axios.get('https://yts-proxy.now.sh/list_movies.json?limit=5&sort_by=rating');
      this.setState({ movies: movies, isLoading: false });
    } catch (error) {
      console.log('Error');
      console.log(error);
    }
  };

  //render() 함수가 실행된 후 componentDidMount() 실행
  componentDidMount() {
    // axios.get('https://yts-proxy.now.sh/list_movies.json');
    // setTimeout(() => {
    //   this.setState({ sec: this.state.sec - 1 });
    // }, 1000);
    this.getMovies();
  }
}

export default App7;

 

>> Movie.js 에서 화면 그려지는 부분 수정 - return 부분

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

function Movie({ id, year, title, summary, poster }) {
  return (
    <div className="movie">
      <img src={poster} alt={title} title={title} />
      <div className="movie-data">
        <h3 className="movie-title">{title}</h3>
        <h5 className="movie-yaer">{year}</h5>
        <p className="movie-summary">{summary}</p>
      </div>
    </div>
  );
}

//정보 가져오기 : id, title, rating...
Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
};

export default Movie;

 

>> 안 쓰는 부분인 id 삭제

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

import './Movie.css';

function Movie({ year, title, summary, poster }) {
  return (
    <div className="movie">
      <img src={poster} alt={title} title={title} />
      <div className="movie-data">
        <h3 className="movie-title">{title}</h3>
        <h5 className="movie-yaer">{year}</h5>
        <p className="movie-summary">{summary}</p>
      </div>
    </div>
  );
}

//정보 가져오기 : id, title, rating...
Movie.propTypes = {
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
};

export default Movie;

 

(5) 스타일링

-App7.js에서 css 파일 로딩

import './App7.css';

-App7.css

.movie-title {
  background-color: black;
  color: azure;
}

-Movie.js

import './Movie.css';

-Movie.css

body {
  background-color: #2f2f2f;
}

5. 영화 앱 마무리

(1) Movies.css

.movies .movie {
  background-color: white;
  margin-bottom: 70px;
  font-weight: 300;
  padding: 20px;
  border-radius: 5px;
  color: #adaeb9;
  box-shadow: 0 14px 27px -5px rgba(50, 50, 90, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.25),
    0 -6px 16px -6px rgba(0, 0, 0, 0.025);
}

.movies .movie a {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) 2fr;
  grid-gap: 20px;
  text-decoration: none;
  color: inherit;
}

.movie img {
  position: relative;
  top: -50px;
  max-width: 150px;
  width: 100%;
  margin-right: 30px;
  box-shadow: 0 30px 60px -12px rgba(50, 50, 90, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3),
    0 -12px 36px -8px rgba(0, 0, 0, 0.025);
}

.movie .movie-title,
.movie .movie-year {
  margin: 0;
  font-weight: 300;
}

.movie .movie-title {
  margin-bottom: 5px;
  font-size: 24px;
  color: #2c2c2c;
}

.movie .movie-genres {
  list-style: none;
  padding: 0%;
  margin: 5px 0px;
  display: flex;
  flex-wrap: wrap;
}

.movie-genres li,
.movie .movie-year {
  margin-right: 10px;
  font-size: 14px;
}

.movie-title {
  background-color: bisque;
}

>> 실행 결과 : 영화 리스트가 아래의 스타일로 출력

 

(2) App7.js

return (
                <Movie
                  key={movie.id}
                  // id={movie.id}
                  year={movie.year}
                  title={movie.title}
                  summary={movie.summary}
                  poster={movie.medium_cover_image}
                  genres={movie.genres}  //추가
                />
              );

(3) Movie.js

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

import './Movie.css';

function Movie({ year, title, summary, poster, genres }) {
  return (
    <div className="movie">
      <img src={poster} alt={title} title={title} />
      <div className="movie-data">
        <h3 className="movie-title">{title}</h3>
        <h5 className="movie-yaer">{year}</h5>
        <!-- ★ 장르 출력과 지정된 스타일 적용 ★ -->
        <ul className="movie-genres">
          {genres.map((genres, index) => {
            return (
              <li key={index} className="movie-genre">
                {genres}
              </li>
            );
          })}
        </ul>
        <p className="movie-summary">{summary.slice(0, 180)}...</p>
      </div>
    </div>
  );
}

//정보 가져오기 : id, title, rating...
Movie.propTypes = {
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired, //추가
  //장르는 배열로 가져오기 때문에 위와 같이 입력
};

export default Movie;
{genres.map((genre, index) => {
            return (
              <li key={index} className="movie-genre">
                {genre}
              </li>
            );
          })}

>> 데이터 출력 및 스타일 지정 완료된 것

 

>> 라우트는 5. 간단실습 아래에


5. async / await 간단 실습

-async_await.js

const axios = require('axios').default;

/** 흐름
 * get 가져온 결과값이 변수 login에 들어감
 * 
 */

//비동기 방식을 사용하지 않았을 경우!!
//정상적인 동작은 되지 않지만 프로그램의 흐름을 파악하기는 쉬움
// function logName(userId) {
//     var login = axios.get('localhost: 8080?userId='+userId);

//     if (login.auth == 'success') {
//       console.log(user.name);
//     }
//   }

//비동기 방식을 사용했을 경우(promise)
//비동기 방식 혹은 콜백 방식에 대한 이해가 있을 경우에만 프로그램의 흐름을 파악할 수 있음.
function logName(userId) {
  axios.get('localhost: 8080?userId=' + userId).then((res) => {
    if (res.auth == 'success') {
      console.log(res.name);
    }
  });
}

//async, await 적용했을 경우
//async/await를 사용하면 콜백에 대한 이해가 없어도 프로그램의 흐름을 쉽게 파악할 수 있음.
async function logName(userId) {
    var login = await axios.get('localhost: 8080?userId='+userId);

    if (login.auth == 'success') {
      console.log(user.name);
    }
  }

console.log('Login Proccess...');
logName('admin');

 


 

 

ㅇㅇㅇ

 

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함