리덕스 미들웨어
redux-promise 패키지를 설치하여 어플리케이션 안에 ajax 리퀘스트를 처리하도록 할 수 있다.
ajax 를 사용하기 위해서 axios 라이브러리 사용한다.(제이쿼리는 너무 기능이 많아서)
// WeatherReducer
export default function(state = null, action) {
console.log("Action received", action);
return state;
}
리덕스 미들웨어는 리듀서가 호출되기 전의 문지기 같은 역할을 하면서 액션을 잠깐 멈출 수 있다. 지금 만들어진 액션의 payload는 프로미스인데, 원래는 리듀서에 넘겨야 하지만 payload가 프로미스인 것을 확인하면 미들웨어가 프로미스가 resolved될 때까지 기다린 다음에 새로운 액션을 만들어 리듀서에게 준다.
////////// Action Creator //////////
import axios from 'axios';
const API_KEY = 'blahblah';
const ROOT_URL =`https://api.openweathermap.org/data/2.5/forecast?appid=${API_KEY}`;
// 오타 방지용으로 액션 타입을 선언하는 스트링을 변수에 담음
export const FETCH_WEATHER = 'FETCH_WEATHER';
export function fetchWeather(city) {
const url = `${ROOT_URL}&q=${city},us`;
const request = axios.get(url);
console.log('req', request);
return {
type: FETCH_WEATHER,
payload: request
}
}
////////// WeatherReducer //////////
import { FETCH_WEATHER } from "../actions/index";
export default function(state = [], action) {
console.log(action.payload);
switch(action.type) {
case FETCH_WEATHER:
return [ action.payload.data, ...state ];
}
return state;
}
위 코드에서 보면 알 수 있듯이 액션 생성함수 내에서도 request를 콘솔에 찍었고, 리턴되는 액션의 payload값도 request이다. 그러나 WeatherReducer에서 전달받은 액션의 payload값을 콘솔에 찍어보면 좀 다르게 나온다.
Redux-Promise를 사용했을 때의 request, action.payload 콘솔 로그
Redux-Promise를 사용하지 않았을 때의 request, action.payload 콘솔 로그
action receive, 그러니까 리듀서에서 액션을 받은 뒤에 콘솔에 찍힌 payload의 형태가 두 경우가 다르다. 리덕스 프로미스를 사용한 경우에는 프로미스 그 자체가 payload로 온 것이 아니라 프로미스 밸류인 객체가 전달되었지만, 리덕스 프로미스를 사용하지 않은 경우엔 프로미스 그 자체가 전달되었다. 즉 원하는 데이터를 추출하여 스테이트에 반영하기 위해서는 리덕스 프로미스를 사용하는 것이 편할 것이다.