[React & NodeJS]영화웹페이지#2

jeje·2021년 6월 30일
1

영화웹페이지

목록 보기
1/5

날짜 : 21.07.01
참고 강의

[React.js]

1. Load More 버튼

1) [LandingPage.js]의 버튼에 onClick 생성

...
...
return(
  ...
  ...
  
  <div style={{ display: 'flex', justifyContent: 'center' }}>
    <button onClick={loadMoreItems}>Load More</button>
  </div>
...
...
)

2) onClick 함수인 loadMoreItems 작성

function LandingPage(props){
  ...
  ...
  const [CurrentPage, setCurrentPage] = useState(0);
  
  // fetch부분이 겹치므로 함수로 빼내어주기
  const fetchMovies = (endpoint) => {

        fetch(endpoint)
            .then(response => response.json())
            .then(response => {

                console.log(response)

                setMovies([...Movies, ...response.results])
                setMainMovieImage(response.results[0])
                setCurrentPage(response.page)

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

        fetchMovies(endpoint);
    }, [])
  
  const loadMoreItems = () => {
        const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=ko&page=${CurrentPage + 1}`;

        fetchMovies(endpoint);
    };
  
}

2. Detail 페이지 만들기

1) [MovieDetail] - [MovieDetail.js] 생성

import React, { useEffect, useState } from 'react';
import { API_URL, API_KEY, IMAGE_BASE_URL } from '../../Config';
import { withRouter } from 'react-router-dom';
import MainImage from '../LandingPage/Sections/MainImage';
import MovieInfo from './Section/MovieInfo';

function MovieDetail(props) {

    let movieId = props.match.params.movieId
    const [Movie, setMovie] = useState([])

    useEffect(() => {
        let endpointCrew = `${API_URL}movie/${movieId}/credits?api_key=${API_KEY}`;

        let endpointInfo = `${API_URL}movie/${movieId}?api_key=${API_KEY}&language=ko`;


        fetch(endpointInfo)
            .then(response => response.json())
            .then(response => {
                console.log(response)
                setMovie(response)
            })


    }, [])


    return (
        <div>
            {/* Header */}
            <MainImage
                image={`${IMAGE_BASE_URL}w1280${Movie.backdrop_path}`}
                title={Movie.original_title}
                text={Movie.overview}
            />

            {/* Body */}
            <div style={{ width: '85%', margin: '1rem auto' }}>

                {/* Movie Info */}
		// MovieInfo.js에 props정보 보내기
                <MovieInfo
                    movie={Movie}
                />

                <br />

                {/* Actors Grid */}

                <div style={{ display: 'flex', justifyContent: 'center', margin: '2rem' }}>
                    <button>Toggle Actor View</button>
                </div>

            </div>

        </div>
    )
}

export default withRouter(MovieDetail);

2) [MovieDetail] - [Section] - [MovieInfo.js] 생성

import React from 'react';
import { Descriptions, Badge } from 'antd';

function MovieInfo(props) {
  	// MovieDetail.js의 props 가져오기
    let { movie } = props;

    return (
        <Descriptions title="Moive Info" bordered>
            <Descriptions.Item label="Title">{movie.original_title}</Descriptions.Item>
            <Descriptions.Item label="release_data">{movie.release_date}</Descriptions.Item>
            <Descriptions.Item label="revenue">{movie.revenue}</Descriptions.Item>
            <Descriptions.Item label="runtime">{movie.runtime}</Descriptions.Item>
            <Descriptions.Item label="vote_average" span={2}>
                {movie.vote_average}
            </Descriptions.Item>

            <Descriptions.Item label="vote_count">{movie.vote_count}</Descriptions.Item>
            <Descriptions.Item label="status">{movie.status}</Descriptions.Item>
            <Descriptions.Item label="popularity">{movie.popularity}</Descriptions.Item>

        </Descriptions>
    )
}

export default MovieInfo;

3) App.js에 Component 추가

import MovieDetail from './components/MovieDetail/MovieDetail';

function App() {
  return (
    <Router>
      <div>
        <Switch>
          <Route exact path="/" component={Auth(LandingPage, null)} />
          <Route exact path="/login" component={Auth(LoginPage, false)} />
          <Route exact path="/register" component={Auth(RegisterPage, false)} />
          <Route exact path="/movie/:movieId" component={Auth(MovieDetail, null)} />

        </Switch>
      </div>
    </Router>
  );
}

export default App;
  • 결과 화면

4) [MovieDetails.js]의 useEffect에 fetch로 출연진 정보 작성

useEffect(() => {
        let endpointCrew = `${API_URL}movie/${movieId}/credits?api_key=${API_KEY}`;

        let endpointInfo = `${API_URL}movie/${movieId}?api_key=${API_KEY}&language=ko`;

        fetch(endpointInfo)
            .then(response => response.json())
            .then(response => {
                console.log(response)
                setMovie(response)
            })


        fetch(endpointCrew)
            .then(response => response.json())
            .then(response => {
                console.log(response)
                setCast(response.cast)
            })
    }, [])

5) [LandingPage.js]의 GridsCards에 landingPage 추가

landingPage를 추가함으로써 GridCards.js에 조건문을 생성하여 조건에 따라 다른 GridCard가 나올 수 있도록 할 수 있음

<GridCards
	landingPage
    	image={movie.poster_path ? `${IMAGE_BASE_URL}w500${movie.poster_path}` : null}
    	movieId={movie.id}
    	movieName={movie.original_title}
/>

6) [GridCards.js] 수정

function GridCards(props) {
  // LandingPage일 때
    if (props.landingPage) {
        return (
            <Col lg={6} md={8} xs={24}>
                <div style={{ position: 'relative' }}>
                    <a href={`/movie/${props.movieId}`}>
                        <img style={{ width: '100%', height: '320px' }} src={props.image} alt={props.movieName} />
                    </a>
                </div>
            </Col>
        )
    } else {
// MovieDetail일 때
        return (
            <Col lg={6} md={8} xs={24}>
                <div style={{ position: 'relative' }}>
                    <img style={{ width: '100%', height: '320px' }} src={props.image} alt={props.characterName} />
                </div>
            </Col>
        )
    }

}

7) 출연진 정보 저장을 위한 Cast useState 작성

function MovieDetail(props){
  const [Cast, setCast] = useState([]);
  
  return(
    <Row gutter={[16, 16]}>
    	{Cast && Cast.map((cast, index) => (
              <React.Fragment key={index}>
              <GridCards
                  image={cast.profile_path ? `${IMAGE_BASE_URL}w500${cast.profile_path}` : null}
                  characterName={cast.name}
              />
       	      </React.Fragment>
         ))}
   </Row>
  )
  
}

8) Toggle버튼 활성화

function MovieDetail(props){
  const [ActorToggle, setActorToggle] = useState(false);
  const toggleActorView = () =>{
        setActorToggle(!ActorToggle);
    }
  
  return(
    <div style={{ display: 'flex', justifyContent: 'center', margin: '2rem' }}>
                    <button onClick={toggleActorView}>Toggle Actor View</button>
                </div>


                {ActorToggle &&
                    <Row gutter={[16, 16]}>
                        {Cast && Cast.map((cast, index) => (
                            <React.Fragment key={index}>
                                <GridCards
                                    image={cast.profile_path ?
                                        `${IMAGE_BASE_URL}w500${cast.profile_path}` : null}
                                    characterName={cast.name}
                                />
                            </React.Fragment>
                        ))}
                    </Row>
                }
  )
}
  • 결과화면

Full Code

Walang Github

Walang Notion

profile
나의 색으로 가득하게

0개의 댓글