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 객체의 존재에 따라 데이터 출력을 달리한다.


  • statemovies 객체가 존재하면 _renderMovies()를 실행하여 영화 정보가 출력되도록 한다.
  • statemovies 객체가 없다면 'Loading' 문자만 웹브라우저에 노출된다.
  • 따라서 state에서 아무런 값이 없는 상태로 마운트된 후 5초가 지나서 componentDidMount()가 실행되어 statemovies 객체가 삽입된다.
  • state에 값에 변화가 생기면서 render()를 재실행한 후 _renderMovies()를 통해 Movie 컴포넌트에 영화 정보를 전달하여 웹브라우저에 노출시킨다.

 

'코딩 연습 > React' 카테고리의 다른 글

PropTypes로 데이터 형태 확인하기  (0) 2019.01.07
Array.prototype.map() 활용하기  (0) 2019.01.07
블로그 이미지

쵸잇

,