넷플릭스 클론을 시작하게 됐다 그럴듯한 웹을 하나 만들어 보고 싶어서 강의를 보기 시작했는데
API를 불러오는 키워드나 방법 필요한 라이브러리를 내가 반복적으로 보고 기억에 남기고 싶어서 적어본다
React 설치
npx create-react-app ./
./은 지금 터미널이 속해있는 해당 경로이다.
폴더를 만들기 전에 폴더명을 입력하여 설치해도 된다
예를 들어 새로운 프로젝트를 movieApp에 저장하고 싶은 경우
npx create-react-app movieApp
Axios
영화정보를 가져올 DB사이트에서 API를 요청하기 위한 라이브러리
npm install axios --save
설치해준다 나의 경우엔 에러가 발생하여
https://velog.io/@s_keyyy/Error-A-complete-log-of-this-run-can-be-found-in
해당 링크 참고하여 해결하였다
API를 불러올 인스턴스를 생성해 주어야 하는데 이 과정에서 반복되는 코드가 많아 따로 js파일을 만들어
인스턴스를 만든 후 수출해주는 과정을 거친다
//axios.js
import axios from 'axios';//설치한 axios를 import해준다
//import는 번역해보니 수입이라 한다 엑시오쓰 수입!
const instance = axios.create({//instans객체 생성
baseURL: 'https://www.themoviedb.org/3',//더무비디비 API를 불러올 베이스url
params: {
api_key: '82c9f7e8df21e783d191d3d4c1f46943',//나의 고유한 key값 회원가입 하면 부여된다
language: 'ko_KR'//불러올 언어 설정
},
});
export default instance;
//기본 수출! 다른 파일에서도 instance를 사용할 수 있다
//requests.js
const requests = {
fetchNowPlaying: 'movie/now_playing',
fetchNetflixOriginals: '/discover/tv?with_networks=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
axios의 베이스url 다음에 다양한 카테고리의 정보를 가져오기 위한 부가적인 url을 저장하는 파일도
따로 생성해 주고 이 두 파일은 api폴더에 담아 분류해준다
이름을 보시면 생각보다 직관적이다 그런데 코메디보단 코믹이 낫지않을까!?
베이스 링크에 requests에 담긴 링크들을 이어붙혀 검색해봤는데 .. 아무것도 안나온다 일단 진행해보기로
https://developer.themoviedb.org/docs
더무비디비의 API공식문서인데 보면서 진행해본다
가장 먼저 해야할 것은 기본적인 앱의 구조를 생각하는 것
퍼블리싱을 할때 앱을 쪼개서 부분부분을 구조화 하는것과 비슷하다
내가 그 동안 했던것과 다른 점은 컴포넌트 별로 구분하여 파일을 생성 한다는 것
구조를 분해했다면 src폴더 내부에 componant 폴더를 생성하여 각각 js, css파일을 만들어준다.
요로케 해줬고 나는 타입스크립트를 적용시켜 만들어 볼 예정이라 다시 해야지..
이렇게 타입스크립트 버전도 만들어 주었다
tsx파일은 jsx를 함께 사용하는 타입스크립트 파일을 의미한다
그래서 api, request는 ts로 만들어 주었고 컴포넌트에선 jsx를 사용할 것 같아서 다른 확장자를 주었다
requests.ts 파일에는 타입 지정도 해주었는데 이제 저 객체 안에 만들어둔 인스턴스들은
string만 사용할 수 있도록 한 것이다
Nav바의 디자인 부터 해보았다!
이렇게 완성 되었고 디자인은 넷플릭스 홈페이지를 참고해서 너비(아니)높이를 맞추었다
호랑이는 실제로 나의 넷플릭스 프사
//Nav.tsx
<nav className={`header-nav ${show && "nav-black"}`}>
<img
className='main-logo'
alt='NetflixLogo'
src='https://i.namu.wiki/i/Ir_vEjL7av085gNIkfxcJu7FSrNAqB6yncaP1bti_Jp7ItJl6XbjcorfORrNo4UwZacu_9BEy-E9KNNRK7LpVw.svg'
onClick={() => (window.location.reload())}
/>
<div className='user-icon-box'>
<img
className='user-icon'
alt='UserLogo'
src="https://occ-0-3683-988.1.nflxso.net/dnm/api/v6/K6hjPJd6cR6FpVELC5Pd6ovHRSk/AAAABW_RdVzkFv_U8BqtQ_vEO0AWvxNrXeEL6CKiTYQfKvvEwRkBlpf1htXe73nZTwsrAUK6nr23wrW2I-x-G0nKHpbVAIwSPC4.png?r=0a8"
/>
<span className='caret'></span>
</div>
</nav>
보시다시피 타입 지정을 전혀 못하고 있는데 .. 그래도 일단 아는대로 만들고 수정해야겠다
꺼무위키에서 로고디자인 가져왔음
/*Nav.css*/
.header-nav{
width: 100%;
height: 68px;
position: fixed;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 5;
background-color: #111;
transition: 1s;
}
.nav-black{
background-color: white;
}
.main-logo{
width: 100px;
height: 30px;
cursor: pointer;
padding-left: 60px;
}
.user-icon-box{
width: 52px;
padding-right: 60px;
}
.caret{
border-color: #fff transparent transparent;
border-style: solid;
border-width: 5px 5px 0;
margin-left: 10px;
transition: transform 367ms cubic-bezier(.21,0,.07,1);
width: 0;
height: 0;
}
const [show, setShow] = useState(false)
useEffect(()=>{
window.addEventListener('scroll',()=>{
if(window.scrollY > 50){
setShow(true)
}else{
setShow(false)
}
})
})
useEffect의 용도를 알아냈다!
그냥 선언해도 동일하게 작동할텐데 왜 쓰려나 싶었는데 동작 순서와 관계가 있었다
useEffect는 HTML을 먼저 읽은 후에 읽힌다고 한다
만약 10000번을 반복하는 for문이 있다고 했을때 그냥 선언하면 그 코드를 먼저 읽느라 HTML렌더링이 늦어진다
그것은 우리의 프로젝트처럼 작은 규모에서는 눈에 띄지 않을수도 있겠지만은 큰 서비스일수록 영향이 클것이다
존안님의 강의를 보고 진행하다보니 생각보다 모르는게 많고 배울게 많아서 좀 늦어지겠지만
차근차근 완성해보아야지!
타입도 지정해야지!