만들면서 배우는 리액트 튜토리얼 - 7.Async와 Await

by - September 01, 2018

이전에 배운 Promise의 .then 사용하면 프로그램이 커졌을  

.then .then .then 끝없이 반복되는 '콜백 지옥'에 빠질 있다

하지만 Async Await 사용하면 문제를 깔끔하게 해결할 있다.

Cf) await async 함수 내에서만 동작한다.

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

class App extends Component {

  state = [

  ]

  componentDidMount() {
    this._getMovies();
  }

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

  _getMovies = async () => {
    // await 함수가 successed 아니라 just finished되면
    // return value 무엇이든 value return한다
    const movies = await this._callApi()
    // 따라서 _callApi() 끝나기 전까지 setState() 실행되지 않는다
    this.setState({
      movies // ES5 movies: movies
    })
  }
 
  _callApi = () => {
    // fetch라는 이름의 promise return
    return fetch('https://yts.am/api/v2/list_movies.json?sort_by=rating')
    .then(potato => potato.json()) // 사람이 읽을 있게 byte -> json으로 변경
    .then(json => json.data.movies)
    .catch(err => console.log(err))
  }

  render() {
    return (
      <div className="App">
        {/*
          this.state.movies 데이터가 존재하면 기존 state mapping 실행하고,
          아니면 Loading... string 띄워준다
        */}
        {this.state.movies ? this._renderMovies() : "Loading..."}
      </div>
    );
  }
}

export default App;

Async, Await 예시


componentDidMount()에는 주로 많은 함수들이 실행된다

그렇기 때문에 componentDidMount() 코드 사이즈를 줄이기 위해서 코드에서는 

기존 내용을 _getMovies()라는 이름의 함수로 새로 선언해서 사용했다.


_getMovies 동시에 여러 API 이용하여 데이터를 가지고 있도록 asnyc 이용했고

Api로부터의 데이터 로딩이 끝나지 않았을 setState 실행되면 안되기 때문에 

_callApi() await 사용했다

, 데이터는 여러 군데에서 동시에 가져올 있지만 데이터를 state 넘기는 것은 

모든 데이터가 로딩된 뒤에 실행된다는 것이다


_callApi() 기존 fetch 코드를 거의 재사용 했는데 우선 fetch promise  

JSON형태로 바꾸고(.then(potato => potato.json())) json.data.movies 통해 

데이터 중에서 movies 데이터를 뽑아 return한다.

movies 객체 안에 이상 우리가 만들었던 poster라는 데이터는 없고 대신 

large_cover_image 존재하기 때문에 poster={movie.large_cover_image} 코드를 변경했다.


마지막으로 컴포넌트의 key map에서 자동생성된 index 사용하는 것이 너무 느리고


이제 영화 데이터에 id 존재하기 때문에 key={movie.id} 바꿔주었다.

You May Also Like

0 comments