Netflix Clone Project 구조 정리

김대현·2020년 4월 12일
1

React Study

목록 보기
3/3
post-thumbnail

Netflix Clone Project 구조

React를 학습하며 진행했었던 Netflix Clone Project에 대한 전체 구조를 기록해두었다.
중간에 개념들도 섞어넣어 정리하여 잊지 않도록 하자.

Page 설계

  • Home : '/'
  • TV : '/tv'
  • Search: '/search'
  • Detail: '/movie/{id}', '/show/{id}'

Container Presenter Pattern

중규모의 React기반의 디자인 패턴이다. 기본적으로 Container는 Data, State를 가지고 api를 불러온다. Container(Class Component)는 Data를 Fetch하는 등 State를 이용한 모든 로직을 처리하며, Presenter(Function Component)는 State를 Props로 받아 해당 데이터들을 보여주는 역할을 한다.

Container Component들 같은 경우에는 주석을 통해 state의 type들을 확인할 수 있고, Function Component들 같은 경우에는 propTypes를 통해 props의 type들을 확인할 수 있다.

React에서 한 Component가 다른 Component와 통신하기 위해서는 props를 통해 전달해야 한다. React에서는 데이터가 한쪽으로만 전달된다. 단방향 통신 흐름은 데이터의 전달 과정을 이해하고 예측하기 수월해진다.

Styled Component

기존에 웹사이트를 개발할 때는 HTML과 CSS, JavaScript는 각자 별도의 파일에 두는 것이 best practice로 여겨졌다. 최근에는 웹 애플리케이션을 여러 개의 재활용이 가능한 컴포넌트 기반 개발 방법이 주류가 되고 있다. 따라서 웹페이지를 여러개의 컴포넌트로 분리하여 각 컴포넌트에 HTML, CSS, JavaScript를 한번에 넣는 형태를 취하고 있는데, 여기에
CSS-in-JS 라이브러리만 사용하면 손쉽게 JavaScript에 삽입할 수 있다.

  • class명 중복을 피할 수 있음
  • props를 받을 수 있음

React-router-dom

React-router-dom 참고

Components

Router Component

  1. Router에서는 BrowserRouter(vs HashRouter)를 사용하였고 위에서부터 Header, Route 구조로 이루어진다.

React Router 종류
1. BrowserRouter

  • Link to 속성에 이동할 경로 기술한다.
  • 새로고침하면 경로 몾찾아서 에러난다.
  1. HashRouter
  • 검색 엔진에 사용될 수 없다.
  • 정적 페이지에 적합하다.

Header Component

  1. Header에서는 withRouter(주로 history에 접근하여 컴포넌트에서 라우터를 조작하는 데 사용한다.)를 사용하여 history의 location의 pathname에 접근할 수 있다. pathname을 이용하여 해당 메뉴에 여러 컴포넌트에 Link를 통해 접근할 수 있는 네비게이션 역할을 맡고 있다.

  2. style을 잠깐 들여다보면 position: fixed를 통해 스크롤시에도 해당 위치를 고정시켰고 Header의 child인 List(ul)는 flex를 주었고 각각의 Item(li)들은 pathname을 이용한 boolean값을 props로 받아 선택시에 아래선에 포인트를 주었다. 또한 react-router-dom의 Link 컴포넌트를 바로 사용하는 것이 아니라 style-component를 이용하여 추가로 디자인을 입혔다.

position
1. static (기본위치) : position 프로퍼티의 기본 값으로 position 프로퍼티를 지정하지 않았을 떄와 같다. 기본적인 요소의 배치 순서에 따라 위에서 아래로, 왼쪽에서 오른쪽으로 순서에 따라 배치되며 부모 요소 내에 자식 요소로서 존재할 때는 부모 요소의 위치를 기준으로 배치된다.
2. relative (상대위치) : 기본 위치(static으로 지정되었을 때의 위치)를 기준으로 좌표 프로퍼티(top, bottom, left, right)를 사용하여 위치를 이동시킨다.
3. absolute (절대위치) : 부모 요소 또는 가장 가까이 있는 조상 요소(static 제외)를 기준으로 좌표 프로퍼티(top, bottom, left, right)만큼 이동한다. 만일 부모 또는 조상 요소가 static인 경우, document body를 기준으로 하여 좌표 프로퍼티 대로 위치하게 된다. 이때 다른 요소가 먼저 위치를 점유하고 있어도 뒤로 밀리지 않고 덮어쓰게 된다. absolute 프로퍼티 선언 시, block 요소의 width는 inline 요소와 같이 content에 맞게 변화되므로 적절한 width를 지정하여야 한다.
4. fixed (고정위치) : 부모 요소와 관계없이 브라우저의 viewport를 기준으로 좌표프로퍼티(top, bottom, left, right)을 사용하여 위치를 이동시킨다. fixed 프로퍼티 선언 시, block 요소의 width는 inline 요소와 같이 content에 맞게 변화되므로 적절한 width를 지정하여야 한다.

Home Component

  1. Router에서 'Routes/Home'의 Home을 import시에 Home 디렉토리의 index.js를 참조하게 되며 index.js는 HomeContainer를 import한 후 export 하는 구조이다.

HomeContainer Component

Componet LifeCycle
1. Mounting : DOM에 Element를 넣는 단계

  • constructor() : 컴포넌트가 초기화 되었을때 state를 초기화한다. props와 같은 인자를 받고 부모 class의 super method를 호출한다.
  • render() : DOM을 위해 JSX을 이용하여 실제 HTML을 반환하는 함수
  • componentDidMount() : 컴포넌트가 렌더된 후 호출되는 함수 (주로 데이터를 fetch할때 사용)
  1. Updating : 컴포넌트가 업데이트 됬을때
  • render() : 컴포넌트가 업데이트 되었을때 다시 호출
  • componentDidUpdate() : 컴포넌트가 다시 렌더링 되었을때 호출되는 함수
  1. Unmounting : 컴포넌트가 DOM에서 제거되었을때
  • componentWillUnmout() : 컴포넌트가 제거되기 직전에 호출되는 함수
  1. HomeContainer는 Class Component이며 Class LifeCycle 구조를 갖는다.

  2. constructor에서는 해당 state를 초기화해주고 초기 render()에서는 state를 통해 presenter component를 렌더링한다.

  3. componentDidMount()에서 api의 movesApi를 호출하여 각각의 정보를 fetch 해오고 setState를 통해 state를 업데이트 한다. 도중 error 발생시에는 error state를 업데이트 시켜주고 최종적으로 finally에서는 loading변수를 false로 할당한다. state가 업데이트 되었으니 cycle대로 render()를 재호출한다.

axios의 장점
1. 구형브라우저를 지원한다.(fetch의 경우는 폴리필 필요)
2. request aborting에 대한 방법을 제공한다.
3. 응답 시간 초과를 설정하는 방법이 있다.
fetch의 장점
1. 라이브러리를 import 하지 않아도 사용할 수 있다.

HomePresenter Component

propTypes는 받은 데이터가 유효한 지 확인하는 데 사용할 수 있는 유효성 검사기의 범위를 내보낸다. 일부 어플리케이션에서 Flow나 TypeSCript와 같이 타입체크를 할 수 있는 자바스크립트 확장을 사용할 수도 있다. 이런 것들을 사용하지 않는다면 React에서 빌트인 타입 체킹이 가능하다.

  1. loading이라는 props를 통해 true일시에는 loading component를 렌더링하고(아직 data를 가져오기 전임을 뜻함) false일시에 data를 통해 렌더링한다.

  2. nowPlaying이 존재하고 있고 길이가 0보다 크다면 Section Component를 props(title, children)와 함께 호출한다. 각각의 movie들은 map function을 이용하여 Poster Component들의 props에 property들을 넣어서 호출한다.

  3. error props가 null이 아닌 경우 Message Component를 props(text, color)와 함께 호출한다.

Section Component

CSS flexbox : 인터페이스 내의 아이템 간 공간 배분과 강력한 정렬 기능을 제공하기 위한 1차원 레이아웃 모델로 설계
1. 주축
flex-direction: row는 main axis가 가로축, cross axis가 세로축
column은 main axis가 세로축, cross axis가 가로축
2. 정렬
justify-content: main axis에 대한 정렬, align-content: cross axis에 대한 정렬
3. 지정 속성
flex-grow: 각 항목은 주축을 따라 분배받은 만큼 사이즈를 늘림
flex-shrink: 각 항목의 사이즈를 수축하는 방법을 정의

CSS Grid는 2차원(행과 열)의 레이아웃 시스템을 제공한다. Flexbox도 훌륭하지만 비교적 단순한 1차원 레이아웃을 위하며, 좀 더 복잡한 레이아웃을 위해 사용한다.

  1. 한개의 Section은 nowPlaying, upcoming, popular을 구분하는 용도이다.

  2. Grid layOut을 사용하여 Poster들을 정렬한다. (1개의 poster는 125px이며 25px의 gap을 갖는다.)

  3. auto-fill은 행/열의 개수를 그리드 컨테이너 및 행/열 크기에 맞게 자동으로 조정한다.

Poster Component

  1. 한개의 Poster는 id를 통해 Detail로 연결할 수 있는 Link를 상위 컴포넌트로 사용하고 있다.

  2. Container는 Image, Rating, Title, Year 정보를 표시하고 있으며 Image는 ImageUrl에 리소스가 없을 때 미리 준비한 no_poster 리소스를 사용한다. Title은 substring을 통해 길이를 조절한다.

  3. Image와 Rating은 hover시에 transition을 통해 투명도를 조정하였다.

SearchContainer Component

  1. Container는 Presenter가 사용할 이벤트에 대한 함수를 메서드로 정의해두고 props를 통해 함수를 전달한다.
  • handleSubmit: form의 기본 event(page를 리로드하는 로직)을 막고 searchTerm state를 통해 searchByTerm을 호출한다.
  • updateTerm : input value가 바뀔시 발생하는 event를 params로 받아 searchTerm state를 업데이트한다.

DetailContainer Component

  1. Route에서 호출된 Detail Container는 route에 관련된 props를 갖고 초기화된다. 해당 props에서 pathname을 사용하여 isMovie state를 초기화한다.

  2. props의 match property의 params 정보를 이용하여 Detail Information을 fetch한다. ES6의 디스트럭처링을 사용하여 object안에 있는 data property 에 접근이 가능하다. fetch하다가 에러가 발생했을 시 error state를 갱신하고 finally시에 loading과 result를 갱신한다.

DetailContainer Presenter

  1. 최상위의 Container에 height을 정해주고 BackDrop div와 Content div를 children으로 포함한다. BackDrop div는 filter blur효과, 투명도0.5, z-index: 0를 주어서 배경 이미지 역할을 한다.

  2. Content는 z-index를 주어서 상단에 노출시키고 Cover, Data, Overview로 구성되어 있다.

  3. Data는 Title, ItemContainer 등으로 구성되어 있다.

profile
FrontEnd Developer with React, TypeScript

1개의 댓글

comment-user-thumbnail
2020년 11월 17일

뷰를 이용해서 넷플릭스 클론 프로젝트를 하려고했는데 좋은글 도움이 많이 됐습니다 :-) 감사합니다 ㅎㅎ

답글 달기