THE MOVIE DB API를 이용한 리액트 프로젝트 - 02

kangdari·2020년 2월 7일
0

API를 호출하고 가져온 결과 값을 렌더링해보겠습니다.

사용한 API입니다.
https://api.themoviedb.org/3/movie/now_playing?api_key=${key}&language=ko&page=1®ion=KR
현재 한국에서 상영중인 영화 리스트를 한국어로 번역하여 데이터를 제공합니다.

MovieList 컴포넌트를 작성했습니다.

// src/components/MovieList.js
( ... )

const MovieList = ({ movies, error, loading }) => {
    if (error) {
        return <MovieListBlock>오류 발생</MovieListBlock>;
    }

    return (
        <MovieListBlock>
            {loading && '로딩중....'}
            {/* 로딩중이 아니고 movies 배열이 존재할 때 렌더링 */}
            {!loading &&
                movies &&
                movies.map(movie => <MovieItem movie={movie} key={movie.id} />)}
        </MovieListBlock>
    );
};

export default MovieList;

로딩 상태를 리듀서에서 관리할 수 있도록 로딩 모듈을 작성하고 루트 리듀서에 등록해주었습니다.

// src/module/loading.js
import { createAction, handleActions } from 'redux-actions';

const START_LOADING = 'loading/START_LOADING';
const FINISH_LOADING = 'loading/FINISH_LOADING';

export const startLoading = createAction(
    START_LOADING,
    requestType => requestType, // Action type = actin.payload
);
export const finishLoading = createAction(
    FINISH_LOADING,
    requestType => requestType,
);

const initialState = {};

const loading = handleActions(
    {
        //// Action type = actin.payload
        [START_LOADING]: (state, action) => ({
            ...state,
            [action.payload]: true,
        }),
        [FINISH_LOADING]: (state, action) => ({
            ...state,
            [action.payload]: false,
        }),
    },
    initialState,
);

export default loading;

이후 movie 모듈의 Thunk 함수에서 API 함수를 호출하는 과정의 전후에 startLoading, finishLoading 액션 생성 함수를 dispatch 해주었습니다.

적용해둔 logger 라이브러리를 통해서 콘솔창에서 실행되는 액션들을 확인할 수
있습니다.


이번에는 렌더링된 영화 리스트에서 특정 영화를 선택하면 상세 페이지로 넘어가도록 작업을 해보겠습니다. App 컴포넌트에서 Detail 컴포넌트를 라우트로 설정했습니다.

function App() {
  return (
    <HashRouter>
      <Route path='/' component={Home} exact />
      <Route path='/movie/:id' component={Detail} />
    </HashRouter>
    );
}

라우트는 기본적으로 컴포넌트에 history, match, location 3개의 props를 전달받습니다. 이 중에 location은 현재 경로에 대한 정보를 가지는데 이것을 사용해보겠습니다.

MovieList 컴포넌트의 일부분입니다. Link 태그를 설정하면서 props 값들을 전달해주었습니다.

(...)
        <MovieItemBlock>
            {/* 영화 선택 시 props 전달 */}
            <Link
                to={{
                    pathname: `/movie/${id}`,
                    state: {
                        id,
                        title,
                        overview,
                        release_date,
                        vote_average,
                        genre_ids,
                        poster_url,
                    },
                }}
            >
(...)

그럼 해당 경로로 설정된 Detail 컴포넌트에서 location.state를 참조하여 전달받은 props를 사용가능합니다.

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

// MovieItem의 Link 태그로 부터 받아온 props값
// location 값 참조
const Detail = ({ location, history }) => {
    if (location.state === undefined) {
        history.push('/');
        return null;
    }

    const {
        title,
        overview,
        release_date,
        vote_average,
        poster_url,
        // genre_ids, // Genre 컴포넌트로 출력
    } = location.state;
    
    return (
( ... )

이제 영화 리스트에서 특정 영화를 선택하면 ~/movie/:id 경로로 페이지가 이동되며
렌더링됩니다.

만약 영화 상세 페이지에서 다른 정보가 더 필요하다면 영화 id 속성 값으로
API 호출하여 데이터를 얻어야 할 것 같습니다.

0개의 댓글