우아한 테크 러닝 3기 세미나 내용 정리 part.4🙌🙌

Jung Hyun Kim·2020년 9월 15일
0

우아한 테크 러닝 3기 세미나 내용 정리 part.4🙌🙌

middleware 알아보기

Middleware 이해하기

  • redux에서 발생하는 action 들이 중간에 거쳐서 나가는 곳을 middleware라고 한다(즉 데이터 처리기 안에 흘러들어와서 프로세싱을 거쳐서 나가는 구조) 중간에 꽂았다는 의미로 middleware로 지칭한다.
  • action 객체가 스토어에서 나오면 output action이 흘러가서 순서대로 흐르는 모습이라고 이해하면 된다 🤓

미들웨어

// index.js 구조
import {createStore} from "./redux"

function reducer(state= {counter : 0}, aaction) {
  switch(action.type ) {
    case "increment" : 
      return {
      ...state,
      counter : state.counter +1 ,
      }
      defualt:
      return {...state}
  }
}
// store에 reducer함수를 넣어준다. 
const store = createStore(reducer)

// 스토어의 변경사항을 구독(subscribe) 하면 변경사항을 꺼내가서 고쳐줌 

store.subscribe(() => {
console.log(store.getState());
})
store.dispatch( {
type : "increment"})

middleware는 동기적으로 작동 되게 되어있음(비동기 액션을 동기처럼 보이게 하는거라고 볼 수 있다.)
reducer는 순수함수 여야 한다(외부와 아무런 dependency없이 작동하게끔 해야 함)
순수하지 않은 작업 == 결과가 항상 일치하지 않은 작업 (ex. 비동기 API 호출)

function api (url) {
return {};} // 이건 동기적 

function api (url,cb) {
setTimeout(()=>{cb()},2000}
           
           
function reducer(state= {counter : 0}, aaction) {
  switch(action.type ) {
    case "increment" : 
      return {
      ...state,
      counter : state.counter +1 ,
      }
      defualt:
      return {...state}
  }
}

//case 문 안에서 스토어의 상태 업데이트는 불가능하다 

const store = createStore()

그럼 비동기 처리는 어떻게 해주어야 할까?💁
middleware에서 처리하는 것

const myMiddleware = store => dispatch => action {
dispatch(action}; 
//지연호출에 대한 개념을 알기 위해서 
//리덕스 공식문서를 더 참고해볼것!👆🆗

function your middleware(Store) {}
  return function (dispatch) {
  return funtion(Action) {
  dispatch(action)
  }}
  
  //클로져라는 background가 있어서 실행이 가능한 것 
  
  function ourMiddleware(store,dispatch,action) {
  dispatch(action); // 
    
  }

인자 두개를 함수 두개로 쪼개는 것을 '커링'이라고 부른다
둘다 실행 함수는 같지만 다른점은 인자의 갯수 차이이다.

myMiddleware를 실행하면

console.log("lob=> "inc");

mymiddleware(store)(store.dispatch)({type : "increment"})
ourmiddleware(store,store.dispatch, {type : "increment"})

미들웨어 만들기

함수로 감싸는 기법(dispatch와 log를 묶는 기법)

function dissspatchAndLog(store, action) {
console.log("dispatching" , action) 
store.dispatch(Action);
console.log("next state", store.getState())}```

// 디스패치 몽키패칭 실행중인 런타임에서 바꾸어 주는 기법

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;
};

이런 구조가 좋게 느껴지지 않는 이유는 하드코딩 이기 때문인데, 맥락으로 풀어보면 함수가 함수를 부르는 이 구조가 핵심이다.

function patchStoreToAddLogging(store) {
  const next = store.dispatch
  store.dispatch = function dispatchAndLog(action) {
    console.log('dispatching', action)
    let result = next(action)
    console.log('next state', store.getState())
    return result
  }
}

const add1 = function(a,b) {
return a+b


const add2 = function (a) {
return function (b) {
return a+b}}

add1(0,20)
add2(10)(20)

const addTen = add2(10)

addTen(20);
addTen(120);

사용자에게 인자와 인자 사이에 개입할 여지를 주는 것 (몽키패칭 숨기기)

미들웨어는 실제로는 첫번째 미들웨어는 사실상 두번째 미들웨어 데이터가 순차적으로 흘러간다.
그래서 next라고 하는건 다음 미들웨어 실행해 라는 의미이다

function logger(store) {
  return function wrapDispatchToAddLogging(next) {
    return function dispatchAndLog(action) {
      console.log('dispatching', action)
      let result = next(action)
      console.log('next state', store.getState())
      return result
    }
  }
}

최종적으로 쓰는 것은

middlewares = Array.from(middlewares).reverse();
//순서를 역전시켜서 원하는 순서를 보장
let lastDispath = store.dispatch

const mymd = store => next => acttion => {
next(action};}

middlewares.forEach(middleware => {lastDispach = middleware(store)(lastDispatch)});
//store and next is called and caugth in closer

Q&A

  1. 일관성있는 코드 작성을 위해 미들웨어를 쓴다면 쭉 미들웨어에서만 api호출을한다.
  2. 자바스크립트 책 추천 => you dont know 시리즈
profile
코린이 프론트엔드 개발자💻💛🤙🏼

0개의 댓글