# TIL-20210406

# todays

  • redux middleware

# content

# redux에서 미들웨어 사용하기

미들웨어는 중간에서 고정적인 처리를 도와주는 역할을 하게 되는데,
redux에서도 dipatch가 일어나는 과정에서 일정한 처리를 할 수 있도록 설정해주게 된다.

예를 들면, 비동기처리에 대한 에러 핸들링 전역에서의 notify설정, logger, testAPI 동작(sentry)등이 있다.
이번에는 logger를 구현하는 방식에 대해 알아본다.

# middleware가 없다면 어떨까?

우리는 매번 dispatch를 하는 과정에서 log를 남기는 action을 같이 실행해주어야 할 것이다.

  1. 손으로 로깅하기
let action = addTodo("Use Redux");

console.log("dispatching", action);
store.dispatch(action);
console.log("next state", store.getState());

매 컴포넌트 핸들러에서 console.log를 실행해야하는 것은 너무 비효율 적이다.

  1. 함수로 만들어 실행하기
function dispatchAndLog(store, action) {
  console.log("dispatching", action);
  store.dispatch(action);
  console.log("next state", store.getState());
}
// at component
dispatchAndLog(store, addTodo("Use Redux"));

함수로 만들어 실행하지만 매번 스토어 값을 넘겨주는등 조금 더 나은 방식이 있는지 찾아볼 필요가 있다.

  1. 디스패치 몽키패칭 적용하기
let next = store.dispatch;
store.dispatch = function dispatchAndLog(action) {
  console.log("dispatching", action);
  let result = next(action);
  console.log("next state", store.getState());
  return result;
};

store.dipatch의 function을 변경하는 몽키패치를 적용해 dispatch가 호출 될 때마다 console.log가 실행될 수 있도록 한다.
한 가지 행동만 적용한다면 여기서 멈춰도 상관이 없다. (프로그램이 로깅만 한다던지, 오류 보고만 한다던지)
!하지만, 우리는 오류 상황이 발생하면 로그도 뜨고 모니터링 툴에도 전달해야 한다면?

function logger(store) {
  let next = store.dispatch; // dispatch 저장
  store.dispatch = function dispatchAndLog(action) {
    // dispatch override
    console.log("dispatching", action);
    let result = next(action);
    console.log("next state", store.getState());
    return result;
  };
}
function moniter(store) {
  let next = store.dispatch; // 현재 스토어에 있는 dispatch를 저장
  store.dispatch = function dispatchMonitor(action) {
    // dispatch override
    try {
      next(action); // 이전 dispatch 실행
    } catch (e) {
      // .. monitor API emit e
      throw e;
    }
  };
}
logger(store);
monitor(store);

두 가지를 동시에 호출하면 store.dispatch 덮어쓰기 되면서 한가지만 적용되게 된다. monkpatch을 가려줄 수 있는 처리기를 하나 만들어 매번 실행 할 수 있게 한다면 해결할 수 있다.

매번 스토어의 dispatch를 덮어쓰면서 안쪽에서 next()를 통해 실행한다.

dispatch를 인자로 받는다면 store에 접근과 기존 dipatch를 통해 모든 middleware를 거치게 된다.

# end

middleware 만들어보기