미들웨어는, 액션이 디스패치(dispatch) 되어서 리듀서에서 이를 처리하기전에 사전에 지정된 작업들을 설정
합니다. 미들웨어를 액션과 리듀서 사이의 중간자라고 이해하시면 되겠습니다.
리듀서가 액션을 처리하기전에, 미들웨어가 할 수있는 작업들은 여러가지가 있는데요. 단순히 전달받은 액션을 콘솔에 기록을 할 수도 있고, 전달받은 액션에 기반하여 액션을 아예 취소시켜버리거나, 다른 종류의 액션들을 추가적으로 디스패치 할 수도 있습니다.
const middleware = store => next => action => {
/* 미들웨어 내용 */
}
위의 이상한 함수 모양이 리덕스에서 제공하는 미들웨어의 "틀"입니다.(저렇게 써라고 권장함ㅇㅇ)
위 미들웨어에서 store는 우리가 아는 그 store, action은 액션 객체, next는 dispatch입니다(왜 next로 했는지 모름)
const middleware = store => next => action => {
console.log('현재 상태 : ', store.getState());
console.log('액션 : ', action);
const result = next(action);
console.log('다음 상태 : ', store.getState());
return result;
}
//현재상태 : {nowState: "inital",payload: 0}
//액션 : {type: INCREASE,nowState: "Increase!",payload: 10} *(increase액션을 했다고 가정)
//다음 상태 : {nowState: "Increase!",payload: 10}
이처럼 action이 reducer로 가기전에 위와 같은 작업이 중간에서 작업(middleware)이 됩니다.
미들웨어의 개념에 대해서 어느정도 감이 왔으면 미들웨어를 사용해봅시다. 리덕스를 사용하는 어플리케이션에서 비동기 작업
을 처리 할 때 가장 기본적인 방법으로는 redux-thunk 라는 미들웨어를 사용하는것입니다.
리덕스를 만든사람이 만들었고 제일 유명한 미들웨어입니다. 이 미들웨어는 객체 대신 함수를 생성하는 액션 생성함수를 작성 할 수 있게 해줍니다. 만약에 특정 액션이 몇초뒤에 실행되게 하거나, 현재 상태에 따라 아예 액션이 무시되게 하려면, 일반 액션 생성자로는 할 수가 없습니다. 하지만, redux-thunk 는 이를 가능케합니다.
//비동기 함수에 들어갈 액션 생성 함수 생성
const printAction = (data) => {
return {
type: PRINT_ASYNC,
nowState: "Asnyc Print!",
payload: data
}
}
//비동기 함수 생성
const printAsync = () => dispatch => {
axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.data)
.then(data => dispatch(printAction(data.title)))
}
//미들웨어 생성
function thunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = thunkMiddleware();
//미들웨어 스토어에 적용
const store = createStore(
Reducer,
initalState,
applyMiddleware(compose(thunk));
)
store.dispatch(increase());
store.dispatch(printAsync());
store.dispatch(decrease());
//now state is 'Increase!' and payload title is '10'
//now state is 'Decrease!' and payload title is '5'
//now state is 'Asnyc Print!' and payload title is 'delectus aut autem'
printAsync함수를 중간에 넣었지만 비동기함수라 콜스택에 들어갔기때문에 나중에 출력되었다. 작동 잘됨
위의 thunkMiddleware가 공식으로 제공되는 thunk미들웨어입니다. npm으로 다운받을 수 있지만 코드가 워낙 짧고 쉽기때문에 굳이 다운받을 필요는 없습니다. 밑에 compose와 applyMiddleware는 리덕스 기본 함수입니다. 미들웨어 작성시 주의사항이 있습니다.