[chapter 6]모달 및 이미지 불러오기

37636 단어 React리액트React

영화 나열을 위한 Row 컴포넌트 생성하기

row component를 app.js에서 5개만 우선 가져와보자.

function App() {
  return (
    <div className="App">

      <Nav />
      <Banner/>
      <Row 
        title="NETFLIX ORIGINALS"
        id="NO"
        fetchUrl={requests.fetchNetflixOriginals}
        isLargeRow
      />
      <Row
        title="Trending Now"
        id = "TN"
        fetchUrl={requests.fetchTrending}
      />
      <Row
        title="Top Rated"
        id = "TR"
        fetchUrl={requests.fetchTopRated}
      />
      <Row
        title="Action Movies"
        id = "AM"
        fetchUrl={requests.fetchActionMovies}
      />
      <Row
        title="Comnedy Movies"
        id = "CM"
        fetchUrl={requests.fetchComedyMovies}
      />
    </div>
  );
}

이런식으로 Row를 5개 작성해준다.
isLargeLow같은 경우 제일 앞에 나오는 큰 카드를 의미하는 것이다.

내려준 Props받아주기

import React from 'react'

export default function Row({isLarge, title, id, fetchUrl}) {
  return <div></div>
  
}

영화 정보 가져오기

import React, { useEffect, useState } from 'react'
import axios from '../api/axios';


export default function Row({isLargeLow, title, id, fetchUrl}) {
    const [movies, setMovies] = useState([]);
    useEffect(()=>{
        fetchMovieData();
    },[]);

    const fetchMovieData = async () => {
        const request = await axios.get(fetchUrl);
        setMovies(request.data.results);
    }


    return <div></div>
}

이런식으로 가져온다.

UI생성하기

    return(

    <section>
        <h2>{title}</h2>
        <div className='slider'>
            <div className='slider__arrow-left'>
                <span className='arrow'>{"<"}</span>
            </div>
    <div id={id} className="row_posters">
        {movies.map(movie => (
            <img
                key={movie.id}
                className={`row__poster ${isLargeRow && "row__posterLarge"}`}
                src={`https://image.tmdb.org/t/p/original/${isLargeRow ? movie.poster_path: movie.backdrop_path}`}
                alt={movie.name}
            />
        ))}
        <div className='slider__arrow-right'>
        <span className='arrow'>{">"}</span>
        </div>

    </div>
        

        </div>
    </section>
    )

UI를 이렇게 생성해준다.


이 자식 하나때문에 가로정렬이 안됐다..
언더바하나 추가하는거 젠장... 이렇게 고쳤으니 이제 슬라이드 기능을 추가해보자.

슬라이드 기능 추가하기

화살표 방향 클릭 시 슬라이드 기능 구현

innerwidth

scrollLeft

을 사용해서

<span
                    className='arrow' 
                    onClick={()=>{
                        document.getElementById(id).scrollLeft -= window.innerWidth - 80;
                    }}>

화살표 버튼을 클릭할때마다 이동하게 만들어주면 된다!

            <div className='slider__arrow-left'>
                <span
                    className='arrow' 
                    onClick={()=>{
                        document.getElementById(id).scrollLeft -= window.innerWidth - 80;
                    }}
                    >
                        {"<"}
                </span>
            </div>
            <div id={id} className="row__posters">
                {movies.map((movie) => (
                    <img
                        key={movie.id}
                        className={`row__poster ${isLargeRow && "row__posterLarge"}`}
                        src={`https://image.tmdb.org/t/p/original/${isLargeRow ? movie.poster_path: movie.backdrop_path}`}
                        loading ="lazy"
                        alt={movie.name}
                    />
                ))}
            </div>
            <div className='slider__arrow-right'>
                <span 
                className='arrow'
                onClick={()=>{
                    document.getElementById(id).scrollLeft += window.innerWidth - 80;
                }}
                >{">"}</span>
            </div>

오른쪽으로 가는것은 플러스를 주면된다!
이렇게 작성하면 성공적으로 이동한다.

Styled component이용해서 Footer 생성


이 부분을 만들어보자.

import React from "react";
import styled from "styled-components";

export default function Footer() {
  return (
    <FooterContainer>
      <FooterContent>
        <FooterLinkContainer>
          <FooterLinkTitle>넷플릭스 대한민국</FooterLinkTitle>
          <FooterLinkContent>
            <FooterLink href="https://help.netflix.com/ko/node/412">
              넷플릭스 소개
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko">
              고객 센터
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko/">
              미디어 센터
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko/">
              이용 약관
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko/node/412">
              자막 및 설정
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko">
              음성 지원
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko/">
              기프트카드
            </FooterLink>
            <FooterLink href="https://help.netflix.com/ko/">
              쿠키 설정
            </FooterLink>
          </FooterLinkContent>
          <FooterDescContainer>
                <FooterDescRights>
                    Netflix Rights Reserved.
                </FooterDescRights>
          </FooterDescContainer>
        </FooterLinkContainer>
      </FooterContent>
    </FooterContainer>
  );
}

const FooterContainer = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 40px 0;
  border-top: 1px solid rgb(25, 25, 25);
  width: 100%;
  position: relative;
  z-index: 100;

  @media (max-width: 769px) {
    padding: 20px 20px;
    padding-bottom: 30px;
  }
`;

const FooterContent = styled.div``;

const FooterLinkContainer = styled.div`
  width: 500px;

  @media (max-width: 768px) {
    width: 100%;
  }
`;

const FooterLinkTitle = styled.h1`
  color: gray;
  font-size: 17px;
`;

const FooterLinkContent = styled.div`
  display: flex;
  justify-content: space-bewteen;
  flex-wrap: wrap;
  margin-top: 35px;

  @media (max-width: 768px) {
    margin-top: 26px;
  }
`;

const FooterLink = styled.a`
  color: gray;
  font-size: 14px;
  width: 110px;
  margin-bottom: 21px;
  text-decoration: none;

  &:hover {
    text-decoration: underline;
  }

  @media (max-width: 768px) {
    margin-bottom: 16px;
  }
`;

const FooterDescContainer = styled.div`
  margin-top: 30px @media (max-width: 768px) {
    margin-top: 20px;
  }
`;

const FooterDescRights = styled.h2`
  color: white;
  font-size: 14px;
  text-align: center;
`;

좀 길긴한데.. styled 컴포넌트로 Footer를 만들어줬다.

영화 자세히 보기 클릭 시 모달 생성하기

import React, { useEffect, useState } from 'react'
import axios from '../api/axios';
import MovieModal from './MovieModal';
import "./Row.css";


export default function Row({isLargeRow, title, id, fetchUrl}){

    const [movies, setMovies] = useState([]);
    const [modalOpen, setmodalOpen] = useState(false);
    const [movieSelected, setMovieSelected] = useState({});

    useEffect(() => {
        fetchMovieData();
    },[fetchUrl]);

    const fetchMovieData = async () => {
        const request = await axios.get(fetchUrl);
        setMovies(request.data.results);
    };

    const handleClick = (movie) =>{
        setmodalOpen(true) //모달 오픈이 트루 
        setMovieSelected(movie);

    }

    return(
    <section className="row">
        <h2>{title}</h2>
        <div className='slider'>
            <div
                className='slider__arrow-left'               
                onClick={()=>{ //스크롤 기능(완)
                        document.getElementById(id).scrollLeft -= window.innerWidth - 80;
                    }}>
                <span
                    className='arrow' 

                    >
                        {"<"}
                </span>
            </div>
            <div id={id} className="row__posters">
                {movies.map((movie) => (
                    <img
                        key={movie.id}
                        className={`row__poster ${isLargeRow && "row__posterLarge"}`}
                        src={`https://image.tmdb.org/t/p/original/${isLargeRow ? movie.poster_path: movie.backdrop_path}`}
                        loading ="lazy"
                        alt={movie.name}
                        onClick={()=> handleClick(movie)}
                    />
                ))}
            </div>
            <div 
                className='slider__arrow-right'
                onClick={()=>{ //스크롤 기능(오)
                    document.getElementById(id).scrollLeft += window.innerWidth - 80;
                }}>
                <span 
                className='arrow'
                
                >{">"}</span>
            </div>
        </div>
        {
            modalOpen && ( //모달 오픈시 
                <MovieModal {...movieSelected} setmodalOpen={setmodalOpen} /> //컴포넌트 가져오기 
            )
        }
    </section>
    )
}

이와같이 모달 오픈시 컴포넌트를 가져올 수 있게 만들었다.
이제 Movie 모달 UI를 생성해보자.

Movie 모달 UI 생성하기

UI생성하기

index.js를 아래와 같이 작성하면

import React from 'react';
import "./MovieModal.css";

function MovieModal({
    backdrop_path,
    title,
    overview,
    name,
    release_date,
    first_air_date,
    vote_average,
    setModalOpen
}){
    return <div className="presentation">
        <div className='wrapper-modal'>
            <div className='modal'>
                <span onClick={()=> setModalOpen(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__content'>
                    <p className='modal__details'>
                        <span className='modal__user_perc'>
                            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>
                </div>
            </div>
        </div>

    </div>;
}

export default MovieModal;


이렇게 모달이 뜬다.

좋은 웹페이지 즐겨찾기