본문 바로가기

Archived(Programming)/ReactJS

ReactJS_4_State

0. 컴포넌트 LifeCycle

React 컴포넌트는 다음과 같은 사이클을 통해 순차적으로 실행된다.

componentWillMount->render->componentDidMount이 순서대로 발생

예를 들어

  • componentWillMount: 영화관련 api요청
  • componentDidMount: 데이터 처리하는데 사용

로 표현할 수 있다.

 

1. 개념

State는 말 그대로 상태를 말하는 것으로 React에서는 컴포넌트의 상태를 이야기한다. React 컴포넌트는 자신의 상태를 저장할 수 있다. props와의 달리 state는 컴포넌트 내부에서 존재하므로 얼마든지 수정이 가능하다. 

 

state는 변경될 때마다 render가 발생한다. state를 직접 변경할 수 없기에 우리는 setState 같은 함수를 사용한다.

참고로, React는 함수형과 클래스형이 있는데 일반적으로 클래스형으로 개발한다.

 

2. 영화앱

setState를 통해 state 값 greeting을 변경하기 예제

import React from 'react';
import './App.css';
import Movie from './Movie.js';

const movies:[
    {
      title: "Matrix",
      poster: "https://m.media-amazon.com/images/M/MV5BNzQzOTk3OTAtNDQ0Zi00ZTVkLWI0MTEtMDllZjNkYzNjNTc4L2ltYWdlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_.jpg"
    },
    {
      title: "Iron Man",
      poster:  "https://www.arthipo.com/image/cache/catalog/genel-tasarim/all-posters/sinema-cinema-film-postersleri/yabanci-filmler/pfilm163-iron-man-movie-poster-demir-adam-poster-1000x1000.jpg"
    },
    {
      title: "Old Boy",
      poster: "https://image.tmdb.org/t/p/original/rIZX6X0MIHYEebk6W4LABT9VP2c.jpg"
    }
]

class App extends Component {

//state 값
  state = {
    greeting: "Hello!"
  }

//state값을 변경하는 함수
  componentDidMount(){
    setTimeout(() => {
      this.setState({
        greeting: 'Hello again!!'
      }) 
    }, 2000) // 2초 후 변경
  }

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

# setState

this.state.movies를 통해 기존의 값을 가져와서 변경도 가능하다. 아래의 예제는 맨 앞에 추가를 하는 방식.

따라서 무한스크롤과 같은 형태도 얼마든지 구현이 가능하며, 다양한 효과를 낼 수 있다(앞에 추가, 뒤에 추가, 변경, 삭제 등등).

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

class App extends Component {

  state = {
    greeting: "Hello!",
    movies:[
      {
        title: "Matrix",
        poster: "https://m.media-amazon.com/images/M/MV5BNzQzOTk3OTAtNDQ0Zi00ZTVkLWI0MTEtMDllZjNkYzNjNTc4L2ltYWdlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_.jpg"
      },
      {
        title: "Iron Man",
        poster:  "https://www.arthipo.com/image/cache/catalog/genel-tasarim/all-posters/sinema-cinema-film-postersleri/yabanci-filmler/pfilm163-iron-man-movie-poster-demir-adam-poster-1000x1000.jpg"
      },
      {
        title: "Old Boy",
        poster: "https://image.tmdb.org/t/p/original/rIZX6X0MIHYEebk6W4LABT9VP2c.jpg"
      }
    ]
  }
  
  componentDidMount(){
    setTimeout(()=> {
      this.setState({
        movies: [
          {
            title: "Transformer",
            poster: "https://upload.wikimedia.org/wikipedia/ko/thumb/e/e4/%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%EB%A8%B8_%EC%98%81%ED%99%94.jpg/250px-%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%EB%A8%B8_%EC%98%81%ED%99%94.jpg"
          },
          ...this.state.movies,
          // 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} /> //key값 부여, key가 없다면 console창에 에러발생
            })}
          </div>
        );
      }
}
export default App;

# loadingState

필요한 데이터가 바로 즉시 존재하지 않아서 이를 불러와서(loading) 사용할 때도 있다.

이 때, loadingState를 사용하면 데이터 없이 컴포넌트를 먼저 로딩하고 데이터가 도착할 때까지 기다리다가 데이터가 도착하면 나의 컴포넌트의 state를 업데이트 하도록 할 수 있다.

 

참고로, 리액트 자체의 기능와 나의 기능에 차이를 두기 위해 _를 쓴다.

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

class App extends Component{

  state={
  }

  componentDidMount(){
    setTimeout(()=> {
      this.setState({
          movies:[
            // ...this.state.movies,
            {
              title: "Spider Man",
              poster:"https://images-na.ssl-images-amazon.com/images/I/A1CcbJfKqJL._SY679_.jpg"
            },
            {
              title: "Matrix",
              poster: "https://m.media-amazon.com/images/M/MV5BNzQzOTk3OTAtNDQ0Zi00ZTVkLWI0MTEtMDllZjNkYzNjNTc4L2ltYWdlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_.jpg"
            },
            {
              title: "Iron Man",
              poster:  "https://www.arthipo.com/image/cache/catalog/genel-tasarim/all-posters/sinema-cinema-film-postersleri/yabanci-filmler/pfilm163-iron-man-movie-poster-demir-adam-poster-1000x1000.jpg"
            },
            {
              title: "Old Boy",
              poster: "https://image.tmdb.org/t/p/original/rIZX6X0MIHYEebk6W4LABT9VP2c.jpg"
            }
          ]
        })
    }, 1000)
  }
  _renderMovies = () =>{
    const movies = this.state.movies.map((movie, index) =>{
      return <Movie title={movie.title} poster={movie.poster} key={index} />
    })
    return movies
  }
  
  render(){
      return (
        <div className="App">
          {this.state.movies ? this._renderMovies() : "Loading"}
        </div>
      );
    }
}
    

export default App;

'Archived(Programming) > ReactJS' 카테고리의 다른 글

ReactJS_6_Fetch_Promise  (0) 2019.09.20
ReactJS_5_Smart_Dumb  (0) 2019.09.20
ReactJS_3_Props  (0) 2019.09.18
ReactJS_2_컴포넌트  (0) 2019.09.18
ReactJS_1_입문  (0) 2019.09.18