React

4. Netflix 앱 만들기 시작

기 도 2023. 5. 7. 01:10

 만들게 될 Netflix 애플리케이션 소개 

메인 화면 구성

-> 왼쪽 상단에 NETFLIX 로고를 표시한다.

-> 오른쪽 상단에는 사용자 프로필 사진을 표시한다.

-> 상단에는 메인 영화를, 그 아래로 다른 영화 목록을 표시한다.

 

NETFLIX 애플리케이션 기능 소개

-> 영화 포스터가 나열되어 있다. (양 옆 화살표를 통해 좌우로 슬라이드 할 수 있다)

-> 스크롤을 아래로 내리면, 네비게이션 바의 배경색이 검게 변한다.

-> 포스터를 클릭하면 해당 영화의 정보를 보여준다.

-> 영화 제목, 평점, 소개, 예고편 등등

 


 Create-React-App으로 리액트 설치하기 

1. 리액트를 설치할 폴더 생성

-> 폴더명은 자유롭게 설정 (react-netflix-clone)

2. 새 터미널에서 npx creat-react-app ./ 

-> ./ 은 해당 폴더에 설치한다는 뜻

 

=> 시작할 때는 항상 이렇게 리액트를 설치한다.


 The Movie DB API Key 생성하기 

https://www.themoviedb.org/ 

 

The Movie Database (TMDB)

Welcome. Millions of movies, TV shows and people to discover. Explore now.

www.themoviedb.org

1. 위 사이트에 회원가입 후, 로그인

-> Settings 에서 API Key 확인 후 복사해둔다.

 

=> API URL 을 통해 영화 포스터, 정보 등등을 가져올 수 있다.

 


 The Movie DB API 요청을 위한 Axios 인스턴스 생성 및 요청 보내기 

Axios 란?

: 브라우저, Node.js 를 위한 Promise API 를 활용하는 HTTP 비동기 통신 라이브러리

-> 백엔드와 프론트엔드가 통신을 쉽게 하기 위해 Ajax 와 더불어 사용한다.

=> The Movie DB 서버에서 영화 정보를 가져올 때 사용할 것이다 !

 

Axios 사용방법

-> Aixos 모듈 설치

-> npm install axios --save

-> aixos.get('API URL')

 

Axios 인스턴스화 하는 이유

: 중복된 부분을 계속 입력하지 않아도 되기 때문.

-> URL에는 반드시 중복되는 부분이 있기 때문.

 

Axios 인스턴스 만드는 순서

1. 인스턴스 생성할 폴더 생성

2. axios.js 소스 코드 작성

-> 중복되는 부분 URL 입력

import axios from "axios";

const instance = axios.creat({
	baseURL: "중복되는 URL 입력",
        params: {
    	api_key: "복사해둔 API Key 입력",
        language: "ko-KR",
    },
});

export default instance;

3. request.js 소스 코드 작성

-> 중복되는 부분 뒷부분 URL을 입력

const requests = {
    fetchNowPlaying: `movie/now_playing`,
    fetchNetflixOriginals: `/discover/tv?with_network=213`,
    fetchTrending: `/trending/all/week`,
    fetchTopRated: `/movie/top_rated`,
    fetchActionMovies: `/discover/movie?with_genres=28`,
    fetchComedyMovies: `/discover/movie?with_genres=35`,
    fetchHorrorMovies: `/discover/movie?with_genres=27`,
    fetchRomanceMovies: `/discover/movie?with_genres=10749`,    
    fetchDocumentaries: `/discover/movie?with_genres=99`,
}

export default requests;

 넷플릭스 애플리케이션 전체 구조 생성하기 

Navigation Bar

-> 로고와 프로필 사진이 표시되는 부분

-> 스크롤을 내리면 검게 변한다.

 

Banner

-> 가장 큰 영화 사진

-> Play 버튼을 누르면 영화 예고편을 실행한다.

 

Row

-> 영화 목록을 나열하는 부분

-> 양 옆 화살표를 눌러 좌우로 슬라이드 한다.

-> 똑같은 컴포넌트에 데이터를 다르게 받아 다양한 종류의 영화 목록을 생성한다.

 

Footer

-> 가장 밑에 정보를 나열하는 부분

-> 고객센터, 개발자 정보 등을 표시한다.

 

=> components 폴더 안에 각 컴포넌트에 관한 파일을 생성한다.

예시) Nav.js 와 Nav.css 


 네비게이션 바 컴포넌트 생성하기 

1. App.js 에 소스코드 작성

const App = () => {
	return (
		<div className="app">
			<Nav />
		</div>
	);
};

 

2. Nav.js 에 소스코드 작성

import React, { useState, useEffect } from "react";
import "./Nav.css";

export default function Nav() {
	const [ show, setShow ] = useState(false);

	useEffect(() => {
		window.addEventListner("scroll", () => {
			if(window.scrollY > 50) {
				setShow(true);
			} else {
				setShow(false);
			}
		});
		return () => {
			window.removeEventListner("scroll", () => {});
		};
	}, []);

	return (
		<nav className={`nav ${show && "nav__black"}`}>
			<img 
				alt="Neflix logo"
				src="이미지 경로"
				class Name="nav__logo"
				onClick={()=>window.location.reload()}
			/>
			<img
				alt="User logged"
				src="이미지 경로"
				class Name="nav__avatar"
			/>
		</nav>
	);
}

-> 로고 이미지를 클릭하면 페이지를 리로드한다.

-> scrollY 는 스크롤을 얼마나 내렸는지를 의미한다.

 

3. Nav.css 에 소스코드 작성

.nav {
    position: fixed;
    top: 0;
    width: 100%;
    height: 30px;
    z-index: 1;
    padding: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition-timing-function: ease-in;
    transition: all 0.5s;
}

.nav__black {
    background-color: #111;
}

.nav__logo {
    position: fixed;
    left: 40px;
    width: 80px;
    object-fit: contain;
}

.nav__avatar {
    position: fixed;
    right: 40px;
    width: 30px;
    object-fit: contain;
}

 

4. 결과

-> 스크롤을 내리면 네비게이션 바가 검게 변하는 모습을 확인할 수 있다.


 이미지 배너 생성하기 

1. 영화 정보 가져오기

const fetchData = async () => {
    //현재 상영중인 영화 정보들 가져오기
    const request = await axios.get(requests.fetchNowPlaying);
    //여러 영화 중 하나의 영화 정보 가져오기
    const movieID =
        request.data.results[
            Math.floor(Math.random() * request.data.results.length)
        ].id;
    //특정 영화의 더 상세한 정보 가져오기
    const {data: movieDetail} = await axios.get(`movie/${movieID}`,{
        params: {append_to_response: "videos"},
        });
    setMovie(movieDetail);
    };

-> 랜덤 숫자 가져오기 Math.floor(Math.random() * max);

 

2. UI 만들기

return (
    <header className="banner"
    style = {{
        backgroundImage: `url("https://image.tmdb.org/t/p/original/${movie.backdrop_path}")`,
        backgroundPosition: "top center",
        backgroundSize: "cover" 
        }}
    >
    <div className="banner__contents">
        <h1 className="banner__title">
            {movie.title || movie.name || movie.original_name}</h1>
        <div className="banner__buttons">
            <button className="banner__button play">
                Play
            </button>
            <button className="banner__button info">
                More Information
            </button>
        </div>
        <h1 className="banner__description">
            {truncate(movie?.overview,50)}</h1>
    </div>
    <div className="banner--fadeBottom" />      
    </header>
  )

3. CSS 작성하기

4. 설명글 자른 후 ... 붙이기

  const truncate = (str, n) => {
    return str?.length > n ? str.substr(0, n-1) + "..." : str;
  };
<h1 className="banner__description">
            {truncate(movie?.overview,50)}</h1>

 

5. 결과


 Styled Component에 대해서

Sytleld Component 란?

: Css-in-JS 라고 하는 JavaScript 파일 안에서 CSS를 처리할 수 있게 해주는 대표적인 라이브러리

 

설치 방법

-> npm install --save styled-components

 

예시

 


 Styled Component를 이용한 비디오 배너 생성하기 

1. play 버튼 클릭시 비디오로 전환하기

  const [ isClicked, setIsClicked ] = useState(false);
  if(!isClicked) {
    return( 
    ...
    else {
    return (
        <Container>
            <HomeContainer>
                <Iframe
                width="640"
                height="360"
                src={`https://www.youtube.com/embed/${movie.videos.results[0].key}
                ?controls=0&autoplay=1&loop=1&mute=1&playlist=${movie.videos.results[0].key}`}
                title="YouTube video player"
                frameborder="0"
                allow="autoplay; fullscreen"
                allowFullScreen = "true"
                allowfullscreen
                ></Iframe>
            </HomeContainer>
        </Container>
        );
    }
}

-> 클릭하지 않았을 때는 이전에 만들어둔 UI 보여주기

-> 클릭하면 iframe 활용하여 유튜브 영상 보여주기


2. styled component 를 이용한 ui 생성하기

const Iframe = styled.iframe`
    width : 100%;
    height: 100%;
    z-index: -1;
    opcitiy: 0.65;
    border: none;

    &::after {
        content:"";
        position: absolute;
        top:0;
        left:0;
        border: 0px;
        width: 100%;
        height: 100%;
    }
`;

const Container = styled.div`
    display: flex;
    justify-contents: center;
    align-items: center;
    flex-direction: column;
    width: 100%;
    height: 100vh;
`;

const HomeContainer = styled.div`
    width: 100%;
    height: 100%;
`;


3. iframe

iframe 이란?

: html inline frame 요소, inline frame의 약자이다.
-> 효과적으로 다른 html 페이지를 현재 페이지에 포함시키는 중첩된 브라우저.
=> iframe 요소를 이용하면 해당 웹 페이지 안에 어떠한 제한 없이 다른 페이지를 불러와서 삽입 할 수 있다.

 

4. 결과