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 꾸미고 어쩌구 해주면 완성!