3. redux-pender 적용, 및 apod 모듈 작성
자! 그러면 프로젝트에 redux-pender 를 적용해봅시다. 먼저 configure.js 에서 middlewares 배열을 추가해줍니다.
import { createa, applyMiddleware, compose } from 'redux';
import penderMiddleware from 'redux-pender';
import modules from './modules';
const configure = () => {
const devTools = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
const composeEnhancers = devTools || compose;
const middlewares = [penderMiddleware()];
const store = createStore(modules, composeEnhancers(
applyMiddleware(...middlewares)
));
return store;
}
export default configure;
그 다음에는, combineReducers 에서 penderReducer 를 추가해주겠습니다. (이 리듀서는 요청의 상태를 대신 관리해줍니다.)
src/modules/index.js
import { combineReducers } from 'redux';
import apod from './apod';
import { penderReducer as pender } from 'redux-pender';
export default combineReducers({
apod,
pender
});
이제 redux-pender 를 사용 할 준비가 되었습니다! 그럼, 프로미스 기반 액션을 만들고, pender 를 통하여 요청을 처리해봅시다! 그 과정에서 apod 모듈도 완성해보겠습니다. 주석을 읽어가면서 코드를 작성해보세요.
src/store/modules/apod.js
import { createAction, handleActions } from 'redux-actions';
import { Map } from 'immutable';
import { pender } from 'redux-pender';
import * as api from 'lib/api';
import moment from 'moment';
// 액션 타입
const PREVIOUS = 'apod/PREVIOUS';
const NEXT = 'apod/NEXT';
const GET_APOD = 'apod/GET_APOD';
// 액션 생성 함수
export const previous = createAction(PREVIOUS);
export const next = createAction(NEXT);
export const getApod = createAction(GET_APOD, date => api.getAPOD(date));
// 리듀서의 초깃값
const initialState = Map({
maxDate: null,
date: null,
url: null,
mediaType: null
});
// 리듀서
export default handleActions({
// 이전 날짜로 설정
[PREVIOUS]: (state) => state.update('date', date => (
moment(date).subtract(1, 'days').format('YYYY-MM-DD')
)),
// 다음 날짜로 설정
[NEXT]: (state) => state.update('date', date => (
moment(date).add(1, 'days').format('YYYY-MM-DD')
)),
// GET_APOD 요청 관리하기
...pender({
type: GET_APOD,
onSuccess: (state, { payload: response }) => { // payload 를 response 라고 부르겠다는 의미
const { date, url, media_type: mediaType } = response.data; // 필요한 레퍼런스를 만들고
// 현재 상태에 maxDate 가 설정되어 있지 않다면 설정하기 위하여 temp 상태 생성
let temp = state;
if(!temp.get('date')) {
temp = temp.set('date', date).set('maxDate', date);
}
return temp.set('mediaType', mediaType).set('url', url);
}
// onPending: (state, action) => state // 요청이 시작하여 대기 중일 때 할 작업
// onError: (state, action) => sate // 오류 났을 때 할 작업
})
}, initialState);