티스토리 뷰
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');
ㅇㅇㅇ
'수업 > └리액트(React)' 카테고리의 다른 글
[08]부트스트랩(Bootstrap) (0) | 2022.04.27 |
---|---|
[07]라우트 (0) | 2022.04.22 |
[00]컴포넌트 실습 - 시간에 따라 출력문 변경 (0) | 2022.04.21 |
[00]리액트 - 컴포넌트(component) (0) | 2022.04.20 |
[00]react 기초 개념_리액트 구성 (0) | 2022.04.20 |
- Total
- Today
- Yesterday
- html layout
- caption-side
- 스크립태그
- 미디어 태그
- selcetor
- typeof
- JavaScript
- 변수
- html pre
- html base tag
- 입력양식
- html
- html input type
- A%B
- BAEKJOON
- initialized
- Java
- input type 종류
- improt
- css
- text formatting
- ScriptTag
- border-spacing
- html atrribute
- CascadingStyleSheet
- empty-cell
- 외부구성요소
- html a tag
- 기본선택자
- scanner
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |