[React] Movie app clone coding : Loading States
4-3. Loading States
우리에게 필요한 데이터가 항상 즉시 존재하는 것은 아니다. 데이터 없이 component가 로딩하고, 데이터를 위해 API를 읽어오고, API가 데이터를 주면 component state를 업데이트 한다.
API call
을 timeout
기능으로 유사하게 구현해본다.
이를 위해, movie list
를 function
으로 이동한다.
1 state = {
2 // 비워짐
3 }
4
5 componentDidMount(){
6 setTimeout(() => {
7 this.setState({
8 movies: [ // movie list를 여기로 이동
9 {
10 title: "Matrix",
11 poster: "https://displate.com/displates/2016-09-30/60a3501bd3167cf9330acef43ab51ab3.jpg?w=280&h=392"
12 },
13 {
14 title: "Full Metal Jacket",
15 poster: "https://cf5.s3.souqcdn.com/item/2016/05/17/10/74/99/15/item_XL_10749915_14378548.jpg"
16 },
17 {
18 title: "Oldboy",
19 poster: "https://posterspy.com/wp-content/uploads/2016/02/Oldboy-by-Clay-Disarray-oct.jpg"
20 },
21 {
22 title: "Start Wars",
23 poster: "http://aidanmoher.com/blog/wp-content/uploads/2011/01/Olly-Moss-Star-Wars.jpeg"
24 },
25 {
26 title: "Trainspotting",
27 poster: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTXZIzbi2UWobCwSZbNtYjdUNvyhhvTt4I9_-7Gf06ZXHdm0trT"
28 }
29 ]
30 })
31 }, 5000) // 1000 = 1초
32 }
{this.state.movies.map((movie, index)
에서 map
을 실행하려는데 states.movies
가 사라졌으므로 에러가 발생한다. 아래와 같이 수정해준다.
1// App.js
2 ...
3 render() {
4 return (
5 <div className="App">
6 Loading // 수정
7 </div>
8 );
9 }
10 ...
영화가 state
에 없을 때는 Loading
을 띄우거나 영화 리스트
가 보이게 만든다.
영화 리스트를 불러올 function을 만든다. 아래와 같이 작성한다.
1// App.js
2 ...
3 _renderMovies = () => {
4 const movies = this.state.movies.map((movie, index) => {
5 return <Movie title={movie.title} poster={movie.poster} key={index} />
6 })
7 return movies
8 }
9
10 render() {
11 return (
12 <div className="App">
13 {this.state.movies ? this._renderMovies() : 'Loading'}
14 </div>
15 );
16 }
17
18 ...
위 코드를 살펴보면 movies
라는 variable
에 데이터를 저장한다. : const movies =
데이터가 없을 때 loading
을 띄우고 있으면 영화정보가 보이게 한다. : {this.state.movies ? this._renderMovies() : 'Loading'}
_renderMovies()
에서 underscore _
를 쓰는 이유는 리액트는 자체 기능이 많기 때문에 리액트 자체 기능과 개발자가 만든 기능에 차이를 두기 위해서이다.
정리
찾고 있는 데이터가 있는지 체크하고 자바스크립트에 물어본 후 true이면 영화 정보를 출력하고, 없으면 loading을 출력한다.
render movies
라는 기능을 실행할 때, 위와 같은 variables
를 출력할 것이다.
해당 variables
에는 mapping
을 통해서 제목, 포스터가 보이게 된다.
movies
를 출력할 때 정렬된 항목(array
) 를 보여주는 것이다.
전체 코드
App.js
1import React, { Component } from 'react';
2import './App.css';
3import Movie from './Movie';
4
5class App extends Component {
6
7 state = {
8
9 }
10
11 componentDidMount(){
12 setTimeout(() => {
13 this.setState({
14 movies: [
15 {
16 title: "Matrix",
17 poster: "https://displate.com/displates/2016-09-30/60a3501bd3167cf9330acef43ab51ab3.jpg?w=280&h=392"
18 },
19 {
20 title: "Full Metal Jacket",
21 poster: "https://cf5.s3.souqcdn.com/item/2016/05/17/10/74/99/15/item_XL_10749915_14378548.jpg"
22 },
23 {
24 title: "Oldboy",
25 poster: "https://posterspy.com/wp-content/uploads/2016/02/Oldboy-by-Clay-Disarray-oct.jpg"
26 },
27 {
28 title: "Start Wars",
29 poster: "http://aidanmoher.com/blog/wp-content/uploads/2011/01/Olly-Moss-Star-Wars.jpeg"
30 },
31 {
32 title: "Trainspotting",
33 poster: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTXZIzbi2UWobCwSZbNtYjdUNvyhhvTt4I9_-7Gf06ZXHdm0trT"
34 }
35 ]
36 })
37 }, 1000) // 1000 = 1초
38 }
39
40 _renderMovies = () => {
41 const movies = this.state.movies.map((movie, index) => {
42 return <Movie title={movie.title} poster={movie.poster} key={index} />
43 })
44 return movies
45 }
46
47 render() {
48 return (
49 <div className="App">
50 {this.state.movies ? this._renderMovies() : 'Loading'}
51 </div>
52 );
53 }
54}
55
56export default App;