만들면서 배우는 리액트 튜토리얼 - 3.Props

by - August 17, 2018


Related image


리액트의 주요 컨셉으로 크게 Prop과 State가 있는데

오늘 배울 것은 이 중 하나인 Prop이다.

Image result for react props


Image result for react props





















State와 Props의 차이



Movie App 구현할 메인 컴포넌트 App 

API를 쓰든 하드코딩으로 직접 데이터를 만들든 모든 영화 데이터를 가지고 있어야하고

이 영화들은 Movie Card 형태로 보여질 것이다.

즉, 메인 컴포넌트가 영화 데이터를 리스트 같은 형태로 갖고있어야 한다는 뜻이다.


리스트 안의 Movie Card에는 해당 영화의 상세 정보(Movie Poster 등) 각각 담길 것이다.

, 부모 컴포넌트가 자식 컴포넌트에게 정보를 전달해 준다는 뜻인데,

이 Props 바로 대표적으로 부모가 자식에게 정보를 사용하는 컨셉이다.

1.1. Props 기본 예시

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

const movies = [
  "Matrix",
  "Full Metal Jacket",
  "Oldboy",
  "Start Wars",
]
class App extends Component {
  render() {
    return (
      <div className="App">
        <Movie title={movies[0]}/>
        <Movie title={movies[1]}/>
        <Movie title={movies[2]}/>
        <Movie title={movies[3]}/>
      </div>
    );
  }
}

export default App;
App.js

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

class Movie extends Component {
    render() {
        console.log(this.props);
        return(
            <div>
                <MoviePoster />
                <h1>Hello this is a movie</h1>
            </div>
        )
    }
}

class MoviePoster extends Component {
    render() {
        return(
            <img src='https://m.media-amazon.com/images/M/MV5BMTM0NjQ4OTgyNV5BMl5BanBnXkFtZTcwOTU2MzQ4Nw@@._V1_.jpg'/>
        )
    }
}

export default Movie;
Movie.js
  

App.js에서 movies라는 이름으로 영화 제목들이 담긴 배열을 만들고

Movie 컴포넌트를 render()에서 return

<div className="App">
  <Movie title={movies[0]}/>
  <Movie title={movies[1]}/>
  <Movie title={movies[2]}/>
  <Movie title={movies[3]}/>
</div>

위와 같이 title이라는 이름의 객체 형태로 넣어서 함께 보내주는 것을 볼 수 있다.

이 객체가 바로 prop인데

이를 받은 Movie 컴포넌트는 {this.prop} 통해 데이터를 이용할 있다.

class Movie extends Component {
  render() {
    return(
      <div>
        <MoviePoster />
        <h1>{this.props.title}</h1>
      </div>
    )
  }
}

1.2. Props 활용 예시

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

const movieTitles = [
  "Matrix",
  "Full Metal Jacket",
  "Oldboy",
  "Star Wars",
]

const movieImages = [
  "https://images-na.ssl-images-amazon.com/images/I/51vpnbwFHrL._SY445_.jpg",
  "https://i.pinimg.com/originals/36/1e/cd/361ecdb85a3767f70810cbe2cdaaf1a4.jpg",
  "https://m.media-amazon.com/images/M/MV5BYjQwZTc3ODktZjk1ZS00N2Y3LWFlYmUtMmQ4M2IwMjZlYTIwXkEyXkFqcGdeQXVyNjQwMzk1MDM@._V1_.jpg",
  "http://cdn.shopify.com/s/files/1/0151/0741/products/Star_Wars_Portrait-NGPS1263_Copy_1024x1024.jpg?v=1504676565",
]

class App extends Component {
  render() {
    return (
      <div className="App">
        <Movie title={movieTitles[0]} poster={movieImages[0]}/>
        <Movie title={movieTitles[1]} poster={movieImages[1]}/>
        <Movie title={movieTitles[2]} poster={movieImages[2]}/>
        <Movie title={movieTitles[3]} poster={movieImages[3]}/>
      </div>
    );
  }
}

export default App;
App.js


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

class Movie extends Component {
  render() {
    return(
      <div>
        <MoviePoster poster={this.props.poster}/>
        <h1>{this.props.title}</h1>
      </div>
    )
  }
}

class MoviePoster extends Component {
  render() {
    return(
      <img src={this.props.poster}/>
    )
  }
}

export default Movie;
Movie.js


App.js movieImages라는 이름으로 영화 포스터 배열을 만들고

Movie컴포넌트를 render  이번에는 poster={movieImage[0]} 명령어를 더

poster라는 이름의 객체 형태로 movieImages  props 보내준다.

그럼 이제 Movie 컴포넌트는 {this.props.poster} 명령어로 해당 데이터를 이용할 있다.

하지만 Movie 포스터는 이 props를 전달해주기 위해 받은 것일 뿐

실제로 poster를 사용할 컴포넌트는 MoviePoster 이므로 

이번에는 Movie컴포넌트에서 MoviePoster 컴포넌트로  props 보내준다.

그러면 이제 moviePoster 컴포넌트도 {this.props.poster} 명령어로 

포스터 데이터를 이용할  있게 된다.


정리하자면 영화 타이틀과 포스터 정보를 메인(App.js) 집어넣고 

그것을  컴포넌트에 props로 전달하여 해당 정보를 출력하는 것이다.

1.3.  Array.map()

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

const movies = [
  {
    title:"Matrix",
    poster:"https://images-na.ssl-images-amazon.com/images/I/51vpnbwFHrL._SY445_.jpg",
  },
  {
    title:"Full Metal Jacket",
    poster:"https://i.pinimg.com/originals/36/1e/cd/361ecdb85a3767f70810cbe2cdaaf1a4.jpg",
  },
  {
    title:"Oldboy",
    poster:"https://m.media-amazon.com/images/M/MV5BYjQwZTc3ODktZjk1ZS00N2Y3LWFlYmUtMmQ4M2IwMjZlYTIwXkEyXkFqcGdeQXVyNjQwMzk1MDM@._V1_.jpg",
  },
  {
    title:"Star wars",
    poster:"http://cdn.shopify.com/s/files/1/0151/0741/products/Star_Wars_Portrait-NGPS1263_Copy_1024x1024.jpg?v=1504676565",
  },
]

class App extends Component {
  render() {
    return (
      <div className="App">
         {/*
movies.map 하면 movie movies 객체가 하나씩 들어가고
화살표 다음 내용을 리턴한다
*/}
        {movies.map(movie =>
          <Movie title={movie.title} poster={movie.poster} />
        )}

        {/*
        {
          movies.map(function(movie) {
            return <Movie title={movie.title} poster={movie.poster} />
          })
        }
*/}
      </div>
    );
  }
}

export default App;



1.2.과 1.3.에서 <div className="App">은 같은 동작을 수행한다.

map 메소드에 익숙하지 않은 사람은 조금 헷갈릴 수 있는데

for in 문과 비슷한 느낌이라고 보면 된다.


위 코드에서 movies.map 하면 

movie(current element of the cycle) movies 객체가 하나씩 들어가고 

화살표 다음 내용을 리턴한다

위 코드로 보면 movie에 movies[0]이 movies[1], movies[2], movies[3]이 순서대로 

들어간다는 것이다.

1.4. Validating Props with prop-type

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './Movie.css';

class Movie extends Component {

  static propTypes = {
    title: PropTypes.string.isRequired,
    poster: PropTypes.string,
  }

  render() {
    return(
      <div>
        <MoviePoster poster={this.props.poster}/>
        <h1>{this.props.title}</h1>
      </div>
    )
  }
}

class MoviePoster extends Component {
  render() {
    return(
      <img src={this.props.poster}/>
    )
  }
}

export default Movie;


위의 내용처럼 static propTypes라는 객체를 통해서 부모 컴포넌트에서 얻는 

데이터의 타입, 존재 유무, 필수 유무 등을 확인 있다

해당 데이터가 조건을 충족하지 경우 에러 메시지가 콘솔에 출력 된다.

validation시 유용하게 쓸 수 있다.

You May Also Like

0 comments