React/넷플릭스 클론
NETFLIX CLONE(React)(2-1) - Home Screen
래모
2022. 7. 24. 13:32
별 난리를 다 쳤는데 query 적용이 안 되길래 진짜 죽고 싶었다....
리액트18이랑 react-query가 호환이 안 되서 그러는 문제였음
근데 npm i react-query@4.0.0-beta.3 이거 하니까 됐어 ㅋㅋ아 짜증나 강의 댓글 한번만 제대로 볼 걸
ㅎㅎ... 진정하고
일단 data의 형태는 아래와 같다.
API 불러오기
axios를 이용할 것이다.
import axios from "axios";
const API_KEY = "10923b261ba94d897ac6b81148314a3f";
const BASE_PATH = "https://api.themoviedb.org/3";
export function getMovies() {
return axios.get(`${BASE_PATH}/movie/now_playing?api_key=${API_KEY}`).then(res => res.data);
}
이 프로젝트는 타입스크립트로 작성하는 것이기 때문에 아까 data를 보고 사용할 요소들의
타입을 지정해줘야 한다 고로 아래와 같이 작성해줌
import axios from "axios";
const API_KEY = "10923b261ba94d897ac6b81148314a3f";
const BASE_PATH = "https://api.themoviedb.org/3";
interface IMovie {
id: number;
backdrop_path: string;
poster_path: string;
title: string;
overview: string;
}
export interface IGetMoviesResult {
dates : {
maximum:string;
minimum:string;
},
page: number,
results : IMovie[];
total_pages:number;
total_results: number
}
export function getMovies() {
return axios.get(`${BASE_PATH}/movie/now_playing?api_key=${API_KEY}`).then(res => res.data);
}
useQuery 이용하기
이제 Home에서 아까 만든 getMovies를 사용할 것이다.
useQuery사용방법은 게시물 중에 있으니까 생략
Wrapper 안에 Loading에 따라 Banner를 넣어주고 그 안에 Title과 Overview를 넣어주었다
function Home() {
const { data, isLoading } = useQuery<IGetMoviesResult>(["movies", "nowPlaying"], getMovies);
console.log(data)
return (
<Wrapper>{isLoading? <Loader>Loading...</Loader> :
<Bannner>
<Title>{data?.results[0].title}</Title>
<OverView>{data?.results[0].overview}</OverView>
</Bannner>
}</Wrapper>
);
}
export default Home;
Banner의 background에는 이미지를 넣어줄 것이다
이미지의 경로가 data안에 저장되어 있을 것이다.
그것을 불러주는 함수를 따로 만들어주자
export function makeImagePath(id: string, format?: string) {
return `https://image.tmdb.org/t/p/${format ? format : "original"}/${id}`;
}
그리고 다시 Home으로 돌아와 Banner에 prop으로 저 경로를 넘겨준다
const Bannner = styled.div<{bgPhoto: string}>`
height: 100vh;
display: flex;
flex-direction: column ;
justify-content: center ;
padding: 60px;
background-image: linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0.5)), url(${(props) => props.bgPhoto}) ;
// 점점 진하게
background-size: cover;
`
...
function Home() {
const { data, isLoading } = useQuery<IGetMoviesResult>(["movies", "nowPlaying"], getMovies);
return (
<Wrapper>{isLoading? <Loader>Loading...</Loader> :
<Bannner bgPhoto = {makeImagePath(data?.results[0].backdrop_path || "")}>
<Title>{data?.results[0].title}</Title>
<OverView>{data?.results[0].overview}</OverView>
</Bannner>
}</Wrapper>
);
}
나머지 css 꾸미고 어쩌구 해주면 완성!