🎆리액트 앱 생성하기

👉 바탕화면에 폴더 생성하기

🛠 vsCode 에디터 오픈하기 ⬇

npx creact-react-app ./


🎬영화 데이터 가져오기

🎇'The Movie DB API' 생성하기

https://www.themoviedb.org/
👉 드라마, 영화들의 정보를 전달해줌 ( 회원 가입 하고 로그인 하기👤 )

🔑API 키 받기

로그인 후 상단 오른쪽 프로필 클릭하고 Settings 들어가기앱 이름, URL, 설명 이런 거(기타 등등)를 넣어주면 됨이 단계 거치면 key 받을 수 있음🙆‍♀️👊


🤷‍♀️데이터 어떻게 가져오는지❓ 어떠한 데이터를 가져오는지❓

여기에서 이미 정해놨음➡어떠한 요청 보내고
이런식으로 요청 보내면 우리가 이러한 데이터를 줄 거야여기다 요청 보내면 최신 무비에 대한 데이터 줄거고
어떤 무비 하나에 대해서 자세한 정보 원해서
두번째 처럼 요청 보내면 그 영화에 대한 디테일한 정보 줄거야

이렇게 다 이미 만들어 놓았음
우리는 알맞은 방법으로 요청 보내기만 하면 됨📢👉 이렇게 같은 부분을 인스턴스로 하나 만들어서 사용하면 훨~씬 좋음👍
만들 때 도움 주는 'Axios 라이브러리'가 있음 ( 비동기 요청 보낼 때 많이 사용하는 것 )

🖼이미지 보여주기👀

⬆ 이렇게 ❗❗


🔍Axios❓

브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리📚
쉽게 말해 백엔드랑 프론트엔드랑 통신을 쉽게하기 위해 AJAX와 더불어 사용🙆‍♀️

📥설치 : npm install axios📁api 폴더 만들기

🗣axios.js - 인스턴스 객체 만들기

axios에서 인스턴스 만들기 위해 제공해주는 메서드➡create

👉 인스턴스 만들 때 넣어주고 싶은 옵션들 ({ 안에 넣어 주면 됨 })공통된 URL➡baseURL❗🔑키 값 받은 거 붙여넣기다른 컴포넌트에서도 쓸거라서 export 해주기

🗣requests.js

1 ) 현재 상영중인 영화 가져올 때는 movie/nowplaying의 경로
2 ) 트랜드한 영화를 가져올 때 :
.tranding/all/week_
3 ) 평점 가장 좋은 영화 가져올 때 : /moive/top_rated
4 ) 액션 장르= 28 / 5 ) 코미디=35 / 6 ) 호러=27 / 7 ) 로맨스=10749 / 8 ) 다큐=99


🐱‍🏍메인페이지

네비게이션 바 - 로고, 검색창 / 배너 / 카테고리카테고리 들어가면 영화들이 나열되어 있음

👀구조

🧩각각의 컴포넌트 만들기

👉 'refce'로 각각 함수형 컴포넌트로 만들기

🎨'Style Component' 사용할 것❗

Css-in-JS라고 하는 JS 파일 안에서 CSS 처리할 수 있게 해주는 대표적인 라이브러리📚📥설치 : npm install styled-components

⬇public>images & videos 압축풀고 끌어다 넣기

🖱네비게이션 바 - 스크롤 내리면 점점 색상 바뀌게 하기

useEffect
👉 실행 : 첨 마운트 됐을 때 state 되고 return 안 그리고 마지막이 useEffect
👉 의존성 배열 아무것도 안 들어가면 한번만 실행됨

🎨🔄색상 어떻게 바뀌게 할까❓

🧩컴포넌트라 props로 값 내려주기 ⬇

가져오기⬇

🤷‍♀️addEventListener 등록하고 Nav 컴포넌트가
더이상 안쓰이면 어떻게 해야할까❓
👉 💥'remove' 해줘야 함❗

App.js

✅inset➡left,right,bottom 다 0을 주는 것 ( 포지션 )

⬇ 이렇게 적용 됨


index.css

이부분도 넣어주기
⬇코드 넣어주면 이렇게 됨


🖍배너에 이미지 가져오기

👉 새로고침하면 계속 다른 이미지 나오게 할 것 ❗

🤷‍♀️이미지 가져오려면 어떻게 해야할까❓

👉 영화나 드라마 데이터 가져와서 그중에 하나를 보여주면 됨 ❗

components>Banner.js

🤔데이터 어디서 가져올 땐 어떤 걸 쓸까❓

요청➡The Movie DB APIuseEffect 안에서 요청 보내기⬆ axios가 fetch를 대신함✅➡axiosInstance 이용해서 비동기 요청 보낼 것🔥

🙆‍♀️데이터 받아올 땐 Get Get Get 사용❗요청 경로는 이미 requests.js에다 써놨음
fetchNowPlaying
⬇ 💡async await : 요청 보낸 다음에 응답이 올 때까지 기다리는 것
비동기인데 동기처럼 소스 코드 작성할 수 있게 해주는 것🤩가져와야 요청 보낼 수 있음요청 잘 보내졌음🎬20개의 영화 데이터가 있음
👉 여기서 배너에 랜덤으로 하나만 가져오게 하고 싶은데 어케 할까❓👉 영화 id
이걸 이용해서 영화 상세한 정보를 가져올거임
"한 번 더 요청" 보내야 함 ❗❗

🗣영화 id로 한 번 더 요청 하기

The Movie DB API에서 { append_to_response: "videos" } 이런식으로
요청 보내면 해당 영화에 대한 비디오 정보도 보내줄게 하고 이미 약속이 되어있는 것🤙
🗣 : "해당 영화에 대한 정보 좀 전달해줘" ( 백엔드 서버한테 요청을 하는 것 )response2 : 콘솔에 출력되었고 Network에 들어가면{ append_to_response: "videos" } 이부분이 들어간 것을 확인할 수 있음🙆‍♀️⬆ 저 두부분은 instance에서 넣어준 것들

moiveDetail 이라는 이름으로여기 있는 데이터들을 접근하고 싶으면➡구조 분해 할당 문법

🤔데이터를 가져왔으면 그 다음 스텝은❓

🧠항상 데이터를 가져왔으면 이 데이터를 '기억' 해야겠죠❗setMoive(movieDetail) 넣어주면 movie라는 상태에 이 객체의 데이터들이 다 들어가게 됨😎


👀배너 UI - Banner.js

// ...
return (
  	<div className='banner'
      style={{
      	// 이미지 경로, 사이즈는 original로, 유니크한 이미지 이름
      	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.original_title}
          </h1>
          
          <div className='banner__buttons'>
            {movie.videos.results[0].key ?
             <button>
              Play 
             </button> 
              : null 
            }
          </div>
          
          <p className='banner__description'>
            {movie.overview}
          </p>
          
    	</div>
    	<div className='banner__fadeBottom' />
    </div>
  // ...

bannerfedeBottom 부분은 배너의 가장 밑 ( 자세히 보면 뿌옇게 보임 )
뿌한 부분 처리해주려고 banner
fadeBottom이 있는 것

⬆ 영화의 description 부분이 없는 이유는 저 영화의 description이 없어서 안 나오는 거✅이미지 가져올 때 경로 체크하기➡백그라운드 이미지 넣을 시 중요title 우선 순위로 가져올 건데 영화마다 없는 것도 있어서
없을 경우는 orginal_title을 가져오게 할 것🙆‍♀️

🤷‍♀️영화 title 없으면 orginal_title로 사용하는 건 어떻게 할까❓

여기까지 나왔음

🎥영화에 대한 트레일러 영상 있으면
버튼 보여주고 없으면 버튼 안보여주기

유튜브 비디오를 보여주는 버튼
이 영상의 id 트레일러가 있음videos에 데이터가 있으면 유튜브 안에 이 영화에 대한 트레일러가 있는거고
안에 데이터 없으면 해당 영화에 대한 트레일러가 없는 것

💁‍♀️있으면 Play 버튼 보여주고 없으면 안보여주게 하기⬆result에 첫 번째 객체에 id가 있으면 Play 버튼 보여주게 할 거임🔑key 있으면 Play 버튼 보여주고 없으면 null 처리 해줌쟤가 없으면 videos results 값이 없을 수 있음
값이 없는데 가져오려고 하면 undefined 에러가 뜸❓ 집어넣으면 해결됨❗
삼항 연산자 물음표랑 저 물음표는 어면히 다름⭕

🤔discription은 어떤 데이터를 가져와야 할까❓

{movie.overview} 넣어주면 영화 줄거리가 잘 불려와짐

🎞비디오 보여주기

👉 Play 버튼 눌렀을 때 새로운 UI 보여줄 거임👀처음에 클릭 안 되어 있게 false로 초기화클릭 되지 않았을 땐 현재 UI 나오게 하고Play 버튼 클릭되었을 땐 새로운 UI를 보여줄 것 ( 영상 )

⏯유튜브에 있는 비디오를 어떻게 가져와서 보여줄 수 있을까❓

이렇게 임베드 할 수 있게 해놨음
이걸 그냥 넣어주기만 하면 됨🙆‍♀️유튜브에서 Share 누르고⬆ Iframe 태그 사용하고 있고 width&height 알아서 지정하고
url은 유니크하게 되어 있음

🎨styled 컴포넌트

// styled-components 라이브러리 사용해
// iframe 스타일 설정하는 컴포넌트 만듦
const Iframe = style.iframe`
	// iframe의 너비를 부모 요소의 전체 너비로 설정
	width: 100%;
	// iframe의 높이를 부모 요소의 전체 높이로 설정
	height: 100%;
	// iframe의 z-index를 -1로 설정하여 다른 요소 뒤에 배치
	z-index: -1;
	// iframe의 불투명도를 0.65로 설정하여 약간 투명하게 만듦
	opacity: 0.65;
	// iframe의 테두리 제거하여 깔끔한 외관을 만듦
	border: none;

	// iframe 위에 겹쳐질 가상 요소 (::after)를 추가
	&::after {
		// 가상 요소의 콘텐츠를 비워둠
		content: "";
		// 가상 요소의 위치를 iframe 내에서 절대 위치로 설정
		position: absolute;
		// 가상 요소의 위쪽을 iframe의 위쪽과 맞춤
		top: 0;
		// 가상 요소의 왼쪽을 iframe의 왼쪽과 맞춤
		left: 0;
		// 가상 요소가 iframe의 전체 너비를 차지하도록 설정
		width: 100%;
		// 가상 요소가 iframe의 전체 높이를 차지하도록 설정
		height: 100%;
	}
`

key}? 뒤에 옵션 추가 작성 할 것
▶자동으로 플레이 되게 하는 것➡autoplay,
🔄계속 돌아가는 것➡loop, 🔈첨에 소리 안 나게 하는 것➡mute

배너에서 Play 버튼 누르면

🎥영상 잘 나오는 것을 볼 수 있음👀

🤔Ifream이란 무엇일까❓

유튜브 비디오 가져오기 위해 사용❗
아이프레임➡HTML Inline Frame 요소이며 'inline frame'의 약자
효과적으로 다른 HTML 페이지를 현재 페이지에 포함시키는
중첩된 브라우저로 iframe 요소 이용하면 해당 웹 페이지 안에
어떠한 제한 없이 다른 페이지 불러와서 삽입할 수 있음
😎


🎈카테고리 컴포넌트 - components>Category.js

App.js에 Category 컴포넌트 가져오기

🐱‍🏍각각의 카테고리 hover 시 비디오 플레이 되게 할 것

첨엔 이미지 hover 하면 비디오

👀반응형은 두가지➡크게 하면 5개로 작게하면 하나로

👉 미디어 쿼리 & 그리드 쓸 것🔥

⬆ 카테고리 다섯 개 묶음 div styled 컴포넌트

⬆ 카테고리 한개 묶음 div Wrap styled 컴포넌트

아직까진 비디오 안 움직일 것🙅‍♀️

<img 안에 src & alt 작성하기🖍

// ...
      <Wrap>
        <img src="/images/viewers-disney.png" alt='disney' />
        <video>
          <source src="/videos/disney.mp4" type="video/mp4" />
        </video>
      </Wrap>
// ...

⬆ 이걸 총 5개 복붙하면

실행하면 카테고리 wrap 5개 따다다다닥 보임👊
hover 할 땐 비디오가 작동 안 됨

🤔hover해도 비디오 작동 안되는 이유 뭘까❓

👉 이렇게 해도 적용 안 됨 ( autoPlay할 땐 muted 해줘야 함🤩 )

이제 적용 됨👍


💁‍♀️Row 만들기 - components>Row.js

👉 한 개의 row 만들어 준다음에 재사용하면 됨✨

App.js에서 Row 컴포넌트 4개 넣어주기

데이터들 받아와야 하니까 각각의 Row에 fetchUrl 넣고 요청하기

⬆ 실행하면 위처럼 됨🙆‍♀️

App.js에 있는 title, id, fetchUrl props로 받아오기

1 ) 데이터 받아오기

fetchUrl이 바뀌면 다시 호출📢

2 ) State에 넣어주기

response.data.results➡State 만든 거에 넣어주기🔥
🎬여러 개의 영화들을 다 넣어줄 것

3 ) UI 화면에 보여주기

⬆ props 해서 title 내려오기 {title}

실행 화면 보면 title 있고 < 왼쪽 화살표 나오고
이미지 엄청 큼지막하게 나오고 > 오른쪽 화살표도 있음

components>Row.css

Row.css 파일 만들고 Row.js 에서 Row.css import 해주기✅

👉 > 화살표 hover 했을 때 조금 커지게 scale(1.5)
👉 첨에 히든 이었으니까 visibility: visible로 ( hover했을 땐 볼 수 있게 )

너무 많아서 Skeep

🖱화살표 클릭했을 때 이동할 수 있게 해주기

🤔< 클릭했을 때 왼쪽으로 가게 > 클릭했을 땐 오른쪽으로 가게 하려면❓

components>Row.js

⬆ 저 부분이 이 부분❗

scrollLeft에다 +1씩 해주면 됨
클릭 했을 때마다 전체(viewport 너비)의 -80한 다음 더해주는 것

left는 right완 반대로 이동하기에 -= 이렇게 해줘야 함


🖱영화 클릭했을 때 해당 영화 상세 모달 페이지🎬

components>Row.js

img 태그 안에 onClick 이벤트 넣어주기

handleClick 함수의 인자로 받아오고 싶은 게 있음
👉 모달 각각의 다른 데이터가 나와야 해서❗

🤷‍♀️모달에서 보여주려는 영화 데이터 받아오게 하려면 어떻게 해야할까❓

handleClick(movie) 이렇게만 하면 계속 함수가 호출됨,,😬
문법적인 부분이라 위처럼 작성하면 됨🙆‍♀️

클릭했을 때만 모달을 오픈하게 할 거라
state 만들기

첨엔 모달을 오픈하고 있지 않으니까 false로 초기값 주기

모달 components 생성하고 Row.js에 가져와서
모달 components를 보여줄 수 있게 할 거임✅
👉 isModalOpen이 true일 때만 보여주게 할 것👀

components>Modal.js

Row.js에서 isModalOpen이 true이면 Modal 컴포넌트를, 아니면 null

실행해서 이미지 클릭하면 true니까 밑에 Modal이 뜨는 걸 확인 할 수 있음👀

데이터 보여주기

movie를 여기로 어떻게 하면 가져올 수 있을까❓

컴포넌트 내부 안에선 데이터를 여기서 저기서 쓸 땐
👉 state에 넣어주면 됨🤩

const [movieSelected, setMovieSelected] = useState({});

⬇

movieSelected={movieSelected} 이렇게 말고
{...movieSelected} 이렇게 데이터 내려주고 싶은데

🤷‍♀️movieSelected={movieSelected} & {...movieSelected} 차이는❓

movieSelected={movieSelected}로 했을 땐 console.log로 출력해보면
객체 데이터 받아와짐
이건 movieSelected 안에 있다면
바로 저런 식으로 가져올 수 있는 것

💻모달 UI - Modal.js

return (
  <div className='presentation' role="presentation">
  	<div className='wrapper-modal'>
      <div className='modal'>
        <span
        	onClick={() => setIsModalOpen(false)}
          	className='modal-close'
        >
          X
        </span>
        
        <img
          	className='modal__poster-img'
          	src={`https://image.tmdb.org/t/p/original${backdrop_path}`}
          alt='modal__poster-img'
        />
        
        <div className='modal__contents'>
          <p
          	  className='modal__details'
          >
            <span>
            	100% for you
            </span>{" "}
            {release_date ? release_date : first_air_date}
          </p>
          <h2 className='modal__title'>
            {title ? title : name}
          </h2>
          <p className='modal__overview'>
          	평점: {vote_average}
          </p>
          <p className='modal__overview'>
          	{overview}
          </p>
        </di v>
      </div>
    </div>
  </div>

profile
안녕하세요! 퍼블리싱 & 프론트엔드 개발 공부 블로그 입니다!

0개의 댓글