관리 메뉴

프론트엔드 정복하기

middleware.js 분석 본문

React/클론코딩-realworld app

middleware.js 분석

GROWNFRESH 2020. 10. 18. 11:23

[ middleware.js 원문 ]

더보기
import agent from './agent';
import {
  ASYNC_START,
  ASYNC_END,
  LOGIN,
  LOGOUT,
  REGISTER
} from './constants/actionTypes';

const promiseMiddleware = store => next => action => {
  if (isPromise(action.payload)) {
    store.dispatch({ type: ASYNC_START, subtype: action.type });

    const currentView = store.getState().viewChangeCounter;
    const skipTracking = action.skipTracking;

    action.payload.then(
      res => {
        const currentState = store.getState()
        if (!skipTracking && currentState.viewChangeCounter !== currentView) {
          return
        }
        console.log('RESULT', res);
        action.payload = res;
        store.dispatch({ type: ASYNC_END, promise: action.payload });
        store.dispatch(action);
      },
      error => {
        const currentState = store.getState()
        if (!skipTracking && currentState.viewChangeCounter !== currentView) {
          return
        }
        console.log('ERROR', error);
        action.error = true;
        action.payload = error.response.body;
        if (!action.skipTracking) {
          store.dispatch({ type: ASYNC_END, promise: action.payload });
        }
        store.dispatch(action);
      }
    );

    return;
  }

  next(action);
};

const localStorageMiddleware = store => next => action => {
  if (action.type === REGISTER || action.type === LOGIN) {
    if (!action.error) {
      window.localStorage.setItem('jwt', action.payload.user.token);
      agent.setToken(action.payload.user.token);
    }
  } else if (action.type === LOGOUT) {
    window.localStorage.setItem('jwt', '');
    agent.setToken(null);
  }

  next(action);
};

function isPromise(v) {
  return v && typeof v.then === 'function';
}


export { promiseMiddleware, localStorageMiddleware }

 

**Promise 형태인지 구분해내는 함수

function isPromise(v) {
  return v && typeof v.then === 'function';
}

typeof 구절은 TypeScript 문법이다. 즉, 위는 어떤 구문이 promise 형태인지를 구분해내는 함수다.

 

TS에서는 type을 구분하기 위해 다음과 같은 식을 쓴다.

<typeof v === 'number'>, <typeof v === 'string'>

 

즉, 'function' 또한 TS 내부에서 이미 우리가 알고있는 그 '함수'로 구분하도록 내장시킨 문법이라 이해하면 되겠다.

 

**promiseMiddleware

: promiseMiddleware 라이브러리를 다운받으면 될 듯 하다.

 

 

**localStorageMiddleware

1 const localStorageMiddleware = store => next => action => {
2   if (action.type === REGISTER || action.type === LOGIN) {
3     if (!action.error) {
4       window.localStorage.setItem('jwt', action.payload.user.token);
5       agent.setToken(action.payload.user.token);
6     }
7   } else if (action.type === LOGOUT) {
8     window.localStorage.setItem('jwt', '');
9     agent.setToken(null);
10   }

11   next(action);
};

line 2 : action.type이 REGISTER 또는 LOGIN일때

line3 : action이 error 가 아니면

line4 : localStorage에 'jwt'라는 key와 action.payload의 user.token을 value값으로 저장한다.

line5 : 그리고 agent.js의 setToken => user.token을 token으로 셋팅한다.

 

line7 : action.type이 LOGOUT이라면

line8 : localStorge에 'jwt라는 key와 '' value값을 저장한다.

line9 : agent.js의 setToken => token값을 null로 셋팅한다.

 

 

**느낀 점 : localStorage 툴을 이용하는 reducer 함수에 대해 middleware를 지정해주는 듯하다.

(agmall에서 auth 체크 시, 썼던 auth middleware와 같은 개념이라고 보면 될 듯 하다.)

=> promiseMiddleware는 라이브러리로 따로 뺀다면

=> localStorageMiddleware는 다른 제목으로 따로 빼도 좋을 듯 하다. 고민해보자.