ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React Container and Presenter Pattern
    Project using React/Cloning Netflix 2021. 5. 9. 05:26

    개요

      React app을 어떻게 만들것인지에 대한 디자인 패턴이다. 하나의 파일 안에 데이터를 처리하는 비지니스 로직과 

    Container

      어떻게 동작하는지와 비지니스 로직과 관련된 코드가 있다. api를 수행하고 state를 조작해서 Presenter에게 넘겨준다.

    Presenter

       사용자가 직접 보고, 조작하는 컴포넌트다. Container가 넘겨준 props를 가지고 html을 구성한다. state 조작은 Container가 다 하기 때문에 Presenter는 state를 조작하지 않는다.

    Movie

    Movie Directory

       Movie page의 directory 구조다. Container와 Presenter 디자인 패턴을 설명하기 위해 완성 본을 가져왔다.

    Movie directory 구조

    index.js

    import MovieContainer from "./MovieContainer";
    
    export default MovieContainer;
    

    MovieContainer

    import { moviesApi } from "api";
    import React from "react";
    import MoviePresenter from "./MoviePresenter";
    
    export default class extends React.Component {
      state = {
        loading: true,
        nowPlaying: null,
        upcoming: null,
        popular: null,
        error: null,
      };
    
      async componentDidMount() {
        try {
          const {
            data: { results: nowPlaying },
          } = await moviesApi.nowPlaying();
          const {
            data: { results: upcoming },
          } = await moviesApi.upcoming();
          const {
            data: { results: popular },
          } = await moviesApi.popular();
    
          this.setState({
            nowPlaying,
            upcoming,
            popular,
          });
        } catch {
          this.setState({
            error: "Can't find movie information.",
          });
        } finally {
          this.setState({
            loading: false,
          });
        }
      }
      render() {
        const { nowPlaying, upcoming, popular, error, loading } = this.state;
        return (
          <MoviePresenter
            nowPlaying={nowPlaying}
            upcoming={upcoming}
            popular={popular}
            error={error}
            loading={loading}
          />
        );
      }
    }
    

      state와 componentDidMount()를 이용해서 state를 조작하고 그 값을 MoviePresenter에게 전달하기만 했다.

    MoviePresenter

    import Helmet from "react-helmet";
    import styled from "styled-components";
    import PropTypes from "prop-types";
    
    import Loader from "Components/Loader";
    import Poster from "Components/Poster";
    import Section from "Components/Section";
    
    const Container = styled.div`
      padding: 10px;
    `;
    
    const MoviePresenter = ({ nowPlaying, upcoming, popular, error, loading }) => (
      <>
        <Helmet>
          <title>Movies | Nomflix</title>
        </Helmet>
        {loading ? (
          <Loader />
        ) : (
          <Container>
            <Section title="Now Playing">
              {nowPlaying.map((movie) => (
                <Poster
                  key={movie.id}
                  id={movie.id}
                  imageUrl={movie.poster_path}
                  title={movie.original_title}
                  rating={movie.vote_average}
                  year={movie.release_date.substring(0, 4)}
                  isMovie={true}
                />
              ))}
            </Section>
            <Section title="Upcoming">
              {upcoming.map((movie) => (
                <Poster
                  key={movie.id}
                  id={movie.id}
                  imageUrl={movie.poster_path}
                  title={movie.original_title}
                  rating={movie.vote_average}
                  year={movie.release_date.substring(0, 4)}
                  isMovie={true}
                />
              ))}
            </Section>
            <Section title="Popular">
              {popular.map((movie) => (
                <Poster
                  key={movie.id}
                  id={movie.id}
                  imageUrl={movie.poster_path}
                  title={movie.original_title}
                  rating={movie.vote_average}
                  year={movie.release_date.substring(0, 4)}
                  isMovie={true}
                />
              ))}
            </Section>
          </Container>
        )}
      </>
    );
    
    MoviePresenter.propTypes = {
      nowPlaying: PropTypes.array,
      popular: PropTypes.array,
      upcoming: PropTypes.array,
      loading: PropTypes.bool.isRequired,
      error: PropTypes.string,
    };
    
    export default MoviePresenter;
    

       MoviePresenter는 MovieContainer로부터 props를 받아와서 UI만을 구성한다.

    참고 자료

    소스 코드

    github.com/zpskek/Nomflix-v2/commit/7d0d4a233cae36e527ed3e27ba432d8dda95aa7e

    'Project using React > Cloning Netflix' 카테고리의 다른 글

    React GlobalStyles.js  (0) 2021.05.09
    React api.js  (0) 2021.05.09
    React Router 설정 with react-router-dom  (0) 2021.05.02
    Cloning Netflix settup  (0) 2021.05.02
    What is React?  (0) 2021.05.02

    댓글

Designed by Tistory.