이번 시간에는 loading states에 대해서 이야기 해보도록 하겠습니다.

여러분이 필요한 데이터가 항상 바로 즉시 존재하지는 않을 겁니다.

데이터 없이 컴포넌트가 로딩을 하고, 데이터를 위해 api를 불러서, 

api가 데이터를 주면, 여러분의 컴포넌트 state를 업데이트 할것입니다. 

api콜을 타임아웃 기능으로 유사하게 구현해보겠습니다.

이를 위해서 영화리스트를 funtion으로 이동하겠습니다.

전 시간까지 코딩한 app.js 파일은 아래와 같습니다.


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 = {
greeting: 'Hello React왕초보',
movies : [
{
title : "Matrix",
},
{
title : "Full Metal Jacket",
},
{
title : "Oldboy",
},
{
title : "Star Wars",
}
]
}

componentDidMount(){
setTimeout(() => {
this.setState({
movies: [
{
title: "신과함께",
},
...this.state.movies
]
});
}, 5000)
}

render() {
return (
<div className="App">
{this.state.movies.map((movie, index) => {
return (
<Movie title={movie.title} poster={movie.poster} key={index} />
);
})}
</div>
);
}
}

export default App;




아래와 같이 코딩을 해주고 새로고침을 하니 에러가 발생하였습니다.


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(){
setTimeout(() => {
this.setState({
movies: [
{
title: "Matrix",
poster:
},
{
title: "Full Metal Jacket",
poster:
},
{
title: "Oldboy",
poster:
},
{
title: "Star Wars",
poster:
}
]
});
}, 5000)
}

render() {
return (
<div className="App">
{this.state.movies.map((movie, index) => {
return (
<Movie title={movie.title} poster={movie.poster} key={index} />
);
})}
</div>
);
}
}

export default App;





×
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.



state.movies가 존재하지 않는다고 에러가 발생한 것입니다.


{this.state.movies.map((movie, index) => {


map을 돌리려고 하는데 states.movies가 없으므로 에러가 발생하였습니다.

여기서 loading states가 필요합니다.

간단하게 loading 이라고 작성해보겠습니다.


render() {
return (
<div className="App">
Loading
</div>
);
}
}


새로고침해서 확인해보면 에러가 발생하지 않고 Loading이라고 뜰겁니다.

영화가 state에 없을 때마다 로딩을 띄우거나 , 영화리스트를 보이도록 하겠습니다.

영화리스트를 불러오는 function을 만들겠습니다.

이름은 render movies 이고, 아래와 같이 작성하겠습니다.


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


위에서 작성한 내용은 movies라는 variable에 데이터를 저장한 것입니다.

그리고 데이터가 없을때 '로딩'을 띄우고, 있으면 영화정보가 보이도록 하려면 다음과 같이 작업하면 됩니다.


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

{this.state.movies ? 라는 부분은 데이터가 있는지 물어보는 것입니다.


데이터가 있으면 movies 를 render하라는 내용입니다. 만약 데이터가 없으면 Loading 을 출력하라는 것입니다.


_renderMovies()

 위에서 _(언더바)를 사용한 이유는 리액트 자체 기능이 많기 때문에 

리액트 자체 기능과 여러분의 기능에 차이를 두기 위해서입니다.

이제 새로고침을 해서 인터넷화면을 확인해보겠습니다.

새로고침을 하면 아래와 같이 Loading이 먼저 출력되고 5초후에 영화 이미지와 함께 리스트가 출력됩니다.






여러분들도 여기까지 잘 출력되었을 것이라고 생각됩니다. 이번시간은 여기까지 하도록 하겠습니다.

고맙습니다.
















+ Recent posts