await, async를 배울 차례 입니다.


await, async는 지난 시간에 작성한 아래 라인들을 조금 더 분명하게 작성해 주는 도구입니다.

componentDidMount() {
.then(response => response.json())
.then(json => console.log(json))
.catch(err => console.log(err))
}


영화들을 state에 올리려면 다음과 같은 작업을 해야 합니다.

componentDidMount() {
.then(response => response.json())
.then(json => {
this.setState({
movies: json.data.movies
})
})
.catch(err => console.log(err))
}


세련되보이지 않습니다. 그리고 애플리케이션이 크면 then 안에 then으로 이어지면서,

call back hell(콜백지옥)에 빠지게 됩니다.

그렇기 때문에 여기서 async, await이라는 것을 쓰게 될겁니다.

위와 같이 코딩하는 대신 새로운 get movies 와 callApi 라는 function을 만들 것입니다. 


import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';




class App extends Component {
//Render : componentWillMount() -> render() -> componentDidMount()
//Update : componentWillReceiveProps() -> shouldComponentUpdate() -> componentwillUpdate() -> render() -> componentDidUpdate

state = {};

componentDidMount() {
this._getMoives();
}

_renderMovies = () => {
const movies = this.state.movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index} />;
});
return movies;
};

_getMoives = async () => {
const movies = await this._callApi()
this.setState({
movies
})
}

_callApi = () => {
.then(response => response.json())
.then(json => json.data.movies)
.catch(err => console.log(err));
};

render() {
return (
<div className="App">
{this.state.movies ? this._renderMovies() : "Loading"}
</div>
);
}
}

export default App;




await의 기능은 call api 기능이 끝나는 것을 기다리는 것입니다. 

성공적으로 수행했을 때만 수행되는 것이 아니고 call api의 return value가 무엇이든지 

그 값을 movies에 넣는다는 것입니다. 

그리고 get movies 컴포넌트의 set state를 movies 로 할 것입니다. 

그 것은 call api의 return value입니다.

set state는 call api작업이 완료되기 전까지는 실행되지 않을 것입니다.

위와 같이 코딩을 완료한 후에 인터넷창을 확인해보겠습니다.






영화의 제목은 왼쪽과 같이 나오지만 포스터가 출력되지 않고 있습니다.

에러메세지를 보면 포스터는 필요한 항목이라고 적혀있는데 value가 undefined 되어 있다라고 나옵니다.

그 이유는 movie 오브젝트가 변경되었기 때문입니다.


_renderMovies = () => {
const movies = this.state.movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index} />;
});
return movies;
};


위에 부분에서 poster를 아래와 같이 large_cover_image 로 변경해줍니다.


_renderMovies = () => {
const movies = this.state.movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.large_cover_image} key={index} />;
});
return movies;
};


수정을 완료하였으면 다시 화면을 확인해보겠습니다.






정상적으로 포스터 이미지까지 잘 출력되는 것을 확인하였습니다.

오늘 수정한 것들을 복습해보겠습니다.

첫번째 작업은 fetch를 call api로 변경하였습니다.

그 다음 get movies라는 function을 사용하였습니다.

get movies는 asynchronous function입니다.

그 안에 movies라는 이름의 const variable을 생성하였습니다. 

그리고 call api 작업이 완료되고 return 하기를 await 했습니다.

call api는 fetch promise 를 return 할 것 인데 이 것은 모든 데이터의 제이슨 이었습니다.

그 안에 movies 가 있는 data라는 이름의 오브젝트도 함께 있었습니다.

그래서 json.data.movies 라는 value는 const movies의 결과값이 되는 것입니다.

그리고 _getMovies 컴포넌트의 state를 movies로 set 한 것입니다.

state 안에 movies가 있으면, render moives라는 function을 불러오라는 명령도 해주었습니다.

그리고 render movies는 movies라는 const를 불러오는데 

이 부분은 영화 타이틀, 포스터(large_cover_image)순으로  매핑을 해줍니다.


그리고 마지막으로 아래와 같이 index 부분을 movie.id로 수정해줍니다.

그 이유는 컴포넌트의 key는 인덱스를 사용하는 것이 느리기 때문 입니다. 

_renderMovies = () => {
const movies = this.state.movies.map((movie ) => {
return <Movie title={movie.title} poster={movie.large_cover_image} key={movie.id} />;
});
return movies;
};



이번 시간은 여기까지 입니다. 고맙습니다.



+ Recent posts