ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React.js - Container + Presenter 패턴
    내가 보기 위해 쓰는 것/React.js 2019. 10. 29. 11:06

    리액트는 Component 단위로 개발한다.

    근데 그거 말고는 딱히 정해진 양식이 없다.

    이벤트 제어도 자유 (권장하는 방식이 있긴 있음) css 스타일링도 자유다.

     

    그래서 너무 허허벌판에 서있는 것 같은 느낌이 들어서 디자인 패턴에 대해 하나 알아두면 그나마 규칙성 있는 정돈된 코드를 만들 수 있지 않을까? 그러니까 가장 유명한 방법인 Container + Presenter 패턴에 대해서 아주 간단하게 ARABOJA.

    우선 Container + Presenter 패턴에 대해서 한마디로 정의하면 !-!

     

    데이터처리와 데이터출력을 분리 (logic과 presenter를 분리)

     

    그러니깐

     

    Container : API Request, Exception Error, setState... ETC...

    Presenter : only Props, UI, no logic

     

    이런 구조로 만드는 것이 Container + presenter 패턴이 되는 것이다

     

    그림판으로 만들었습니다.

     

    사실, 이걸 몰랐는데도 사용했던 컴포넌트가 토이프로젝트에 있다.

     

    소스가 이것 저것 많이 있는데 우리는 Pattern을 알기위해서 이 글을 보고 있으니 구조만 알고 넘어가면 될 것 같다.

     

    1. Container (TopAlbum Component)

     

    import React, { Component } from 'react'
    import OneAlbum from './OneAlbum.js'
    
    export default class TopAlbum extends Component {
    
      state = {
        currentAlbum: 0
      }
    
      componentDidMount() {
        this._listMusic()
      }
    
      _listMusic = async () => {
        const albums = await this._callApi()
        await this.setState({
          albumList: albums
        })
        this._callOneAlbum()
      }
    
      _callApi = () => {
        return fetch('제가 쓴 API ^^')
        .then(album => album.json())
        .catch(err => console.log(err))
      }
    
      _callOneAlbum = () => {
        const album = this.state.albumList.albums.album
        const axelel = album.map((info, index) => {
          return <OneAlbum artist={info.artist.name} albumName={info.name} image={info.image[2]["#text"]} key={index} />
        })
        return axelel
      }
    
      render() {
        return (
          <div className="columns is-mobile">
            <div className="column is-full">
              <div className="columns is-mobile is-padding">
                <div className="column">
                  <h3 className="is-size-3 has-text-weight-bold is-title">Top Albums</h3>
                </div>
                <div className="column is-2 is-pulled-right is-pulled-bottom has-text-right">
                  <a href="#" className="is-size-6 has-text-grey">more</a>
                </div>
              </div>
              <hr className="has-background-grey"/>
              <div className="columns is-padding is-touch is-4-touch">
                {this.state.albumList ? this._callOneAlbum() : 'Loading...'}
              </div>
            </div>
          </div>
        )
      }
    }
    

    0. 어차피 아래내용은 음악 정보를 API로 가져와서 데이터를 props로 OneAlbum 컴포넌트에 넘기는 내용이다. 스킵해도 된다.

    1. ComponentDidMount에서 listMusic 함수를 부른다.

    2. listmusic에서 callApi 함수를 부르고 return 값을 변수에 담는다.

    3. callApi에서 API를 json 형식으로 받아와서 return 한다.

    4. 받아온 json 데이터를 state에 담고 callOneAlbum 함수를 부른다.

    5. callOneAlbum에서 데이터를 정리해서 props로 전달하고 호출한다. 

     

    그럼 OneAlbum 컴포넌트는... 보여주기만 해야 할 것이다!!!!

     

    2. Presenter (OneAlbum Component)

    import React, { Component } from 'react'
    
    export default class OneAlbum extends Component {
    
      static defaultProps = {
        artist: 'Artist',
        albumName: 'Album',
        image: 'Loading'
      }
    
      render() {
        return (
          <div className="column box">
            <a href="#" className="has-text-black-ter is-flex-mobile is-hover-scaleup">
              <figure className="image is-inline-block">
                <img src={this.props.image} alt={this.props.albumName} />
              </figure>
              <p>
                <span className="title is-size-6 is-size-4-mobile">{this.props.albumName}</span>
                <br/>
                <span className="subtitle is-size-7 is-size-5-mobile has-text-grey">{this.props.artist}</span>
              </p>
            </a>
          </div>
        )
      }
    }
    

     

    받은 props 값을 바탕으로 보여주기만 한다.

     

    TopAlbum Component의 render 결과

     

    핵심!

    Container : 데이터 로직 처리~~~ 이것저것 해서 props로 넘긴다.

    Presenter : 그걸 props로 받아서 보여주기만 한다

    댓글

Designed by Tistory.