Component State는 컴포넌트 안에서 쓸 수 있는 객체이다.
그리고 this.setState()를 활용하여 리액트만의 장점을 확인해보자
import React, { Component } from 'react';
import './App.css';
// Movie.js에서 Movie 클래스를 가져온다
import Movie from './Movie'
// extends를 사용하여 Component를 가져와야 App 이름의 컴포넌트를 만들 수 있다
class App extends Component {
// state는 컴포넌트 안에서 사용되는 객체
// 특징은 state가 바뀔 때마다 render()가 실행된다
state = {
movies: [
{
title: "Matrix",
poster: "https://cdn.vox-cdn.com/thumbor/veUKpCnSKflt86VfCpTfyUqEfYQ=/0x0:1280x720/1200x800/filters:focal(538x258:742x462)/cdn.vox-cdn.com/uploads/chorus_image/image/52198011/c6f5a81cb0fcc1c0e5ae3cba9cc4f40ae35476cb.0.jpeg",
},
{
title: "Oldboy",
poster: "https://static01.nyt.com/images/2018/10/18/arts/18terracehouse/18terracehouse-articleLarge.jpg?quality=75&auto=webp&disable=upscale",
},
{
title: "Terrace House",
poster: "https://cdn.vox-cdn.com/thumbor/GltBWgYa-A_SKHFx2CKHEr93Zvw=/0x0:5760x3840/1200x0/filters:focal(0x0:5760x3840):no_upscale()/cdn.vox-cdn.com/uploads/chorus_asset/file/9898277/_DSC_I1A7700.JPG",
},
{
title: "Suits",
poster: "https://i.ytimg.com/vi/4qBl7_t0M_U/maxresdefault.jpg",
},
{
title: 'Heart Signal',
poster: 'https://t1.daumcdn.net/cfile/tistory/2165C83C58A206D523',
}
]
}
App 컴포넌트 밖에 있던 movies 객체를 컴포넌트 안에 위치한 state에 담았다.
state는 컴포넌트 안에서만 쓸 수 있는 객체이다.
특이점은 함수를 통해 state에 담긴 값이 변경될 경우 자동으로 render() 메소드를 재실행시킨다.
// 컴포넌트가 마운트(트리에 삽입되면)되면 작동하는 메소드
// state 값을 설정하면 render를 재실행한다
componentDidMount(){
// ()는 function()과 같은 의미
setTimeout(() => {
this.setState({
movies: [
// state 객체에서 영화정보가 담긴 movies 값을 불러온다
...this.state.movies,
// 새로 추가할 데이터를 입력한다
{
title: 'Heart Signal',
poster: 'https://t1.daumcdn.net/cfile/tistory/2165C83C58A206D523',
}
})
}, 5000)
}
마운트 후 componentDidMount() 메소드가 호출된다.
- setTimeout()은 this.setState()를 원하는 시간(5000=5초)이 지나서 호출되도록 하기 위함이다.
- () => {}은 function(){}과 동일한 내용이다.
- ...this.state.movies를 기존 데이터인 moives를 전부 읽어오는 것이다.
- 따라서 기존 데이터에 새로운 영화 데이터를 추가 입력하여 state의 값에 변화를 주었다.
render() {
return (
<div className="App">
{/* 리스트에 map 메소드를 사용하여 각 객체의 데이터를 컴포넌트로 전달 */}
{/* index는 각 객체에 id 값을 넣어주며 key값으로 전달한다 */}
{this.state.movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index}/>
})}
</div>
);
}
}
export default App;
state의 값이 변화가 되면서 render() 메소드는 재실행된다.
- state에 추가로 저장된 movies 데이터를 Movie 컴포넌트로 전달하여 기존 영화정보에서 5초 후 더 늘어난 영화 정보가 노출된다.
삼항연산자를 활용하여 리액트만의 극적인 효과 나타내기
동시에 나만의 메소드 만들기
class App extends Component {
state = {
}
componentDidMount(){
setTimeout(() => {
this.setState({
movies: [
{
title: "Matrix",
poster: "https://cdn.vox-cdn.com/thumbor/veUKpCnSKflt86VfCpTfyUqEfYQ=/0x0:1280x720/1200x800/filters:focal(538x258:742x462)/cdn.vox-cdn.com/uploads/chorus_image/image/52198011/c6f5a81cb0fcc1c0e5ae3cba9cc4f40ae35476cb.0.jpeg",
},
{
title: "Oldboy",
poster: "https://static01.nyt.com/images/2018/10/18/arts/18terracehouse/18terracehouse-articleLarge.jpg?quality=75&auto=webp&disable=upscale",
},
{
title: "Terrace House",
poster: "https://cdn.vox-cdn.com/thumbor/GltBWgYa-A_SKHFx2CKHEr93Zvw=/0x0:5760x3840/1200x0/filters:focal(0x0:5760x3840):no_upscale()/cdn.vox-cdn.com/uploads/chorus_asset/file/9898277/_DSC_I1A7700.JPG",
},
{
title: "Suits",
poster: "https://i.ytimg.com/vi/4qBl7_t0M_U/maxresdefault.jpg",
},
{
title: 'Heart Signal',
poster: 'https://t1.daumcdn.net/cfile/tistory/2165C83C58A206D523',
}
]
})
}, 5000)
}
state에 작성했던 movies 값을 비워두자
- this.setState()에 movies 값을 그대로 가져온다.
// _(언더바)를 사용해 나만의 메소드와 리액트 자체 메소드에 구분을 주었다.
// state에서 movies 값을 map() 메소드에 적용하여 새로운 배열을 만들어 movies 객체에 담아서 반환
_renderMovies = () => {
const movies = this.state.movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index}/>
})
return movies
}
render() 메소드 안에 작성했던 map() 메소드를 가져온다
- _renderMovies는 나만의 메소드이므로 리액트 자체 메소드와 구분 짓기 위해 _(언더바)를 사용한다.
- map()을 통해 만들어진 배열을 새로이 movies 변수에 담아서 반환한다.
render() {
return (
<div className="App">
{/* 삼항연산자 사용 */}
{/* 컴포넌트 state에서 movies 값이 있다면 _renderMovies()를 실행하고 없으면 'Loading' 문자 출력 */}
{this.state.movies ? this._renderMovies() : 'Loading'}
</div>
);
}
}
export default App;
삼항연산자를 사용하여 state에서 movies 객체의 존재에 따라 데이터 출력을 달리한다.
- state에 movies 객체가 존재하면 _renderMovies()를 실행하여 영화 정보가 출력되도록 한다.
- state에 movies 객체가 없다면 'Loading' 문자만 웹브라우저에 노출된다.
- 따라서 state에서 아무런 값이 없는 상태로 마운트된 후 5초가 지나서 componentDidMount()가 실행되어 state에 movies 객체가 삽입된다.
- state에 값에 변화가 생기면서 render()를 재실행한 후 _renderMovies()를 통해 Movie 컴포넌트에 영화 정보를 전달하여 웹브라우저에 노출시킨다.
'코딩 연습 > React' 카테고리의 다른 글
PropTypes로 데이터 형태 확인하기 (0) | 2019.01.07 |
---|---|
Array.prototype.map() 활용하기 (0) | 2019.01.07 |