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 호출하여 데이터를 얻어야 할 것 같습니다.