본문 바로가기
REACT

[클론코딩] 무비앱 시리즈 #4

by kmyobin 2022. 7. 6.

#4 Landing Page 만들기 (1)

 

Landing Page : 이용자가 최초로 보게되는 웹페이지

를 만들어보자

 

1. 웹사이트 꾸미기

client-src-components-views-LandingPage

저 파일에 들어가서

import React from 'react'
import { FaCode } from "react-icons/fa";

function LandingPage() {
    return (
       <div style={{width:'100%', margin: '0'}}>

        {/*Main Image*/}

        <div style={{diwth:'85%', margin: '1rem auto'}}>

            <h2>Movies by latest</h2>
            <hr />

            {/*Movie Grid Cards*/}

        </div>

        <div style={{display:'flex', justifyContent: 'center'}}>
            <button>Load More</button>
        </div>

       </div>
    )
}

export default LandingPage

을 적어준다

html 배운지 오래돼서 다 까먹음 T_T

 

그리고 react창을 열어줄

npm run dev

을 이용해서 완성된 웹 페이지를 보려고 했는데

오류가 났다

구글링 해서 나랑 똑같은 오류가 나신 분의 블로그를 참고했다

https://shinye0213.tistory.com/267

 

[Node.js ] 'concurrently'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙

'concurrently'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. [따라하며 배우는 노드, 리액트 시리즈] 영화 사이트 만들기 02. Boiler-Plate & MongoDB 연결 Ⅰ. boilerplate.

shinye0213.tistory.com

암튼 코드 실행하는 폴더 위치를 바꿨더니 고쳐졌다(아직까지 모르겠음)

 

2. Moive API에서 정보 가져오기

Config.js 파일에 다시 들어가서 API_KEY도 상수 설정을 해준다

export const API_KEY = '2a5252309012d1c05db353ef71d0174d'

그 다음 LandingPage.js에 코드를 추가한다.

useEffect를 써줄 것이기 때문에 import 추가하고

API_URL, API_KEY 상수를 이용하기 위해 import 추가함

import React, {useEffect} from 'react'
import {API_URL, API_KEY} from '../../Config';

	useEffect(() => {
        const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;

        fetch(endpoint) // 인기있는 영화 가져오기
        .then(response => response.json()) // 결괏값 가져오기
        .then(response => console.log(response))

    }, [])

그리고 창을 봤는데

TypeError: Cannot read property 'prototype' of undefined

 

에러가 떴다

분명히 난 똑같이 따라했는데?

구글링을 해서 원인을 찾아냈다

https://velog.io/@juho00ng/TypeError-Cannot-read-property-prototype-of-undefined

 

TypeError: Cannot read property 'prototype' of undefined

TypeError: Cannot read property 'prototype' of undefined

velog.io

첫 번째 줄 때문에 에러 난 거 였음

첫 번째 줄 지워줬더니 해결됐다

 

다시 리액트 창으로 들어가보았다

강사분이 console창을 잘 들어가시길래 그것도 모르는 나는 구글링해서 찾음

크롬창 우측 상단에 있는 점 3개 클릭 - 도구 더보기 - 개발자 도구 - Console

 

어 근데 에러가 뜬다

504 gateway

구글링 해보았지만 원인을 아는 사람이 아무도 없으므로 걍 넘어가자

result창을 보면 가장 인기 있는 영화들을 20개씩 보여주는 것을 알 수 있다

요즘은 닥터스트레인지가 유명한가봄

 

그 다음 MovieState에 넣어줘야되므로 useState를 사용한다

영화를 20개씩 다루므로 배열 사용함

function LandingPage() {

    const [Movies, setMovies] = useState([])

    useEffect(() => {
        const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;

        fetch(endpoint) // 인기있는 영화 가져오기
        .then(response => response.json()) // 결괏값 가져오기
        .then(response =>{
            setMovies([response.results])

        } )


    }, [])

 

사이트를 들어가자마자 뜨는 큰 화면은 따로 폴더를 파서 만들어 줄 것이다

LandingPage 폴더 안에 Sections라는 폴더를 하나 생성해주고, MainImage.js 파일을 생성한다

client-src-components-views-LandingPage-Sections 폴더 생성

코드를 작성한다

import React from "react";

function MainImage(props){
  return(
    <div style = {{background: `linear-gradient(to bottom, rgba(0,0,0,0)
    39%, rgba(0,0,0,0)
    41%, rgba(0,0,0,0.65)
    100%),
    url('${props.image}'), #1c1c1c`,
      height: '500px',
      backgroundSize: '100%, cover',
      backgroundPosition: 'center, center',
      width: '100%',
      position: 'relative'
      }}>
      <div>
        <div style={{position: 'absolute', maxWidth: '500px', bottom: '2rem', marginLeft: '2rem'}}>
          <h2 style={{ color: 'white' }}> title </h2>
          <p style={{ color: 'white', fontSize: '1rem'}}> description</p>
        </div>
      </div>
    </div>
  )
}

export default MainImage

그 다음 LandingPage.js로 넘어와서 작성할 건데,

MainImage.js 코드를 가져올 것이므로 import MainImage from './Sections/MainImage';를 추가해주었다

또한 #3에서 상수 설정 해주었던 포스터 URL을 가져와 쓸 것이기 때문에 import에 IMAGE_BASE_URL을 추가해주었다

import React, {useEffect, useState} from 'react'
import { FaCode } from "react-icons/fa";
import {API_URL, API_KEY, IMAGE_BASE_URL} from '../../Config';
import MainImage from './Sections/MainImage';

function LandingPage() {

    const [Movies, setMovies] = useState([])
    const [MainMovieImage, setMainMovieImage] = useState(null)

    useEffect(() => {
        const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;

        fetch(endpoint) // 인기있는 영화 가져오기
        .then(response => response.json()) // 결괏값 가져오기
        .then(response =>{
            console.log(response)
            setMovies([response.results])
            setMainMovieImage(response.results[0])
        } )


    }, [])


    return (
       <div style={{width:'100%', margin: '0'}}>

        {/*Main Image*/}
        {MainMovieImage && 
            <MainImage image={`${IMAGE_BASE_URL}w1280${MainMovieImage.backdrop_path}`} />
        } 
        

        <div style={{diwth:'85%', margin: '1rem auto'}}>

            <h2>Movies by latest</h2>
            <hr />

            {/*Movie Grid Cards*/}

        </div>

        <div style={{display:'flex', justifyContent: 'center'}}>
            <button>Load More</button>
        </div>

       </div>
    )
}

export default LandingPage

이 코드에서

        {MainMovieImage && 
            <MainImage image={`${IMAGE_BASE_URL}w1280${MainMovieImage.backdrop_path}`} />
        }

여기에 있는 &&를 보면, MainMovieImage가 있을 경우 아래의 코드를 실행한다는 의미이다.

{MainMovieImage &&} 없이 하면,,

backdrop_path를 할 때 필요한 MainMovieImage가 없는데 렌더링을 이미 해버렸다는 뜻이기 때문에 에러가 난다

아 그리고 '보다 `쓰는게 유용한 것 같다

왜냐하면 강사님이 그렇게 쓰시기 때문이다 (지식은 모방으로부터~)

 

아무튼 고쳐서 실행하면

닥스

잘 뜬다

 

저기 있는 title이랑 description도 정보를 가져와서 넣어보자

아까 LandingPage.js에 있던 {MainMovieImage &&} 안에 있는 코드에 title, text를 추가해준다

여기에 있는 original_title, overview를 가져옴

 

{MainMovieImage && 
            <MainImage 
                image={`${IMAGE_BASE_URL}w1280${MainMovieImage.backdrop_path}`} 
                title={MainMovieImage.original_title}
                text={MainMovieImage.overview}
            />
}

들여쓰기 잘못했더니 오류나더라,, 다들 들여쓰기를 생활화 합시다,,

그리고 MainImage.js로 가서 props로 연결해준다

<h2 style={{ color: 'white' }}> {props.title} </h2>
<p style={{ color: 'white', fontSize: '1rem'}}> {props.text}</p>

 

잘 ~ 뜬다

 

댓글