redux Middleware
action을 dispatch하기 전 후의 로깅, 비동기 작업 등의 확장적인 작업들을 더욱 쉽게 할 수 있게 해주는 기능이다.
대표적인 redux middleware 라이브러리로는 redux-thunk, redux-sage가 있다.
middleware 예시1)
import { createStore, applyMiddleware } from 'redux';
const firstMiddleware = (store) => (dispatch) => (action) => {
// 기능 추가 (action을 dispatch하기 전에 실행)
console.log("액션이 dispatch되기 전에 실행!", action);
dispatch(action);
// 기능 추가 (action을 dispatch한 후 subscribe된 행동이 일어난 후에 실행!
// 즉, state 업데이트 된 후 실행!)
console.log("액션이 dispatch 됨, state가 업데이트 되고
subscribe된 행동이 일어난 후 실행!");
};
const enhancer = applyMiddleware(firstMiddleware);
const store = createStore(reducer, initialState, enhancer);
- 삼단 고차함수로 정의.
예시 2)
const thunkMiddleware = (store) => (dispatch) => (action) => {
if (typeof action === "function") {
// 인자 순서는 상관 없음, action creator에서 맞춰주면 됨! dispatch는 꼭 포함!
return action(store.dispatch, store.getState, extraArgument);
}
return dispatch(action);
}
const enhancer = applyMiddleware(firstMiddleware, thunkMiddleware);
const store = createStore(reducer, initialState, enhancer);
// async action creator
const logIn = (data) => {
return (dispatch, getState, extraArgument) => {
dispatch(logInRequest({
type: 'LOG_IN_REQUEST',
data
}));
try {
// 비동기 작업 수행
setTimeout(() => {
dispatch({
type: "LOG_IN_SUCCESS",
data
});
}, 2000);
} catch (err) {
dispatch({
type: "LOG_IN_FAILURE",
data: err,
});
}
};
};
기본적으로 action은 object, but 함수로도 올 수 있다. action이 함수일 경우 비동기를 제어한다는 것!
- 즉, action creater가 객체를 return 시 → 동기 action creator action creator가 함수를 return 시 → 비동기 action creator
- store.dispatch만 가지고는 비동기 작업을 구현할 수 없지만, 위와 같이 thunkMiddleware를 껴서 비동기 action을 만들어서 수행할 수 있다.
(middleware 사용 → 비동기 action을 dispatch 할 경우 → 동기 액션을 실행하고 비동기 작업 후 비동기 작업이 완료됐을 때 다시 동기 작업을 실행하는 조합)
⇒ 특정 액션이 몇초뒤에 실행되게 하거나, 현재 상태에 따라 아예 액션이 무시되게 할 수 있다. - 위의 로직이 redux-thunk 라이브러리 로직이다.
redux-thunk
npm i redux-thunk
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
const store = createStore(modules, applyMiddleware(ReduxThunk));
export default store;