redux middleware

studying  · 3 mins read

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;

references