티스토리 뷰

반응형

# 리덕스

import { createStore, actionCreator } from "./redux-middleware";

function reducer(state = {}, { type, payload }) {
  switch (type) {
    case "init":
      return {
        ...state,
        count: payload.count
      };
    case "inc":
      return {
        ...state,
        count: state.count + 1
      };
    case "reset":
      return {
        ...state,
        count: 0
      };
    default:
      return { ...state };
  }
}

const logger = (store) => (next) => (action) => {
  console.log("logger: ", action.type);
  next(action);
};

const monitor = (store) => (next) => (action) => {
  setTimeout(() => {
    console.log("monitor: ", action.type);
    next(action);
  }, 2000);
};

const store = createStore(reducer, [logger, monitor]);

store.subscribe(() => {
  console.log(store.getState());
});

store.dispatch({
  type: "init",
  payload: {
    count: 1
  }
});

store.dispatch({
  type: "inc"
});

const Reset = () => store.dispatch(actionCreator("reset"));
const Increment = () => store.dispatch(actionCreator("inc"));

Increment();
Reset();
Increment();

reducer, subscribe, dispatch가 모두 따로 동작하지만 모두 동기적이다. 순서가 보장된다.

리듀서는 반드시 순수함수로 작성되어야 한다.

 

Api 호출은 순수하지 않다. 비동기다. 사이드이펙트가 일어난다.

순수하지 않은 함수를 어떻게 다룰것인가?

 

멱등성 : 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질 (MDN 링크)

 

리듀서 안에서 api를 호출하면 리덕스에게 반환하는 상태값이 없다.

리듀서는 값을 반드시 반환해야하는 동기함수이기 때문에 비동기 처리는 리듀서 내에서 불가능하다.

 

# 미들웨어

사이드이펙트가 있는 비동기 작업은 리듀서 밖에서 하자! 해서 나온게 미들웨어.

 

미들웨어는 리덕스 공식문서에 잘 나와있음…

미들웨어는 커링 방식과 몽키패칭 기법을 사용한다.

 

## 커링

인자를 여러개 받는 함수를 하나씩 쪼개는 기법

const myMiddleware = store => dispatch => action => {
	dispatch(action);
}

function yourMiddleware(store) {
	return function(dispatch) {
		return function(action) {
			dispatch(action);
		}
	}
}

function ourMiddleware(store, dispatch, action) {
	dispatch(action);
}

myMiddleware(store)(store.dispatch)({ type: ‘inc’ }); // 커링 방식
ourMiddleware(store, store.dispatch, { type: ‘inc’ });

커링 기법을 사용하면 사용자가 별도의 작업을 중간에 추가할 수 잇음.

리덕스 미들웨어에 커링기법을 사용하는 이유는 사용자인 리덕스가 중간에 알아서 순차적으로 처리할 수 있도록 여지를 주기 위함.

 

## 몽키패칭

런타임 환경에서 코드를 바꿀수 있는 기법? 함수 바꿔치기

let next = store.dispatch; // 기존 함수는 변수에 대입
store.dispatch = function dispatchAndLog(action) {} // 새로운 함수 대입

 

## 미들웨어와 플러그인 차이

  • 미들웨어
    • 데이터 흐름의 중간에 꽂혀서 적용되는 것.
    • 모든 데이터에 적용, 꽂힌 순서대로 흐른다.
  • 플러그인
    • 어떨땐 적용하고 어떨땐 적용안하고 선택할 수 있는 것.

 

## 미들웨어를 사용하는 이유는?

일관성.

Api 호출을 리듀서 바깥에서 하는거라면 굳이 미들웨어를 안써도 되지만, 

그렇게 하면 어떨 때는 dispatch를 호출하고 어떨 때는 다른 모듈에 있는 비동기 api 함수를 호출하는 식으로 일관성이 없어진다.

차이를 아는 개발자가 미들웨어를 사용하지 않은 코드를 본다면 이상하게 느낄 것이다.

 

 

## 리덕스 미들웨어 코드

// redux-middleware.js
export function createStore(reducer, middlewares = []) {
  let state;
  const listeners = [];
  const publish = () => {
    listeners.forEach(({ subscriber, context }) => {
      subscriber.call(context);
    });
  };

  const dispatch = (action) => {
    state = reducer(state, action);
    publish();
  };

  const subscribe = (subscriber, context = null) => {
    listeners.push({
      subscriber,
      context
    });
  };

  const getState = () => ({ ...state });
  const store = {
    dispatch,
    getState,
    subscribe
  };

  middlewares = Array.from(middlewares).reverse();
  let lastDispatch = store.dispatch;

  middlewares.forEach((middleware) => {
    lastDispatch = middleware(store)(lastDispatch);
  });

  return { ...store, dispatch: lastDispatch };
}

export const actionCreator = (type, payload = {}) => ({
  type,
  payload: { ...payload }
});
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함