18.3.2.2 비동기 카운터 만들기

    기존에 thunk 함수로 구현했던 비동기 카운터를 이번에는 redux-saga를 사용하여 구현해 봅시다. 우선 라이브러리를 설치해 주세요.

    $ yarn add redux-saga

    그리고 counter 리덕스 모듈을 열어서 기존 thunk 함수를 제거하고, INCREMENT_ASYNCDECREMENT_ASYNC라는 액션 타입을 선언하세요. 해당 액션에 대한 액션 생성 함수도 만들고, 이어서 제너레이터 함수를 만듭니다. 이 제너레이터 함수를 사가(saga)라고 부릅니다.

    modules/counter.js

    import { createAction, handleActions } from 'redux-actions';
    import { delay, put, takeEvery, takeLatest } from 'redux-saga/effects';
    
    const INCREASE = 'counter/INCREASE';
    const DECREASE = 'counter/DECREASE';
    const INCREASE_ASYNC = 'counter/INCREASE_ASYNC';
    const DECREASE_ASYNC = 'counter/DECREASE_ASYNC';
    
    export const increase = createAction(INCREASE);
    export const decrease = createAction(DECREASE);
    // 마우스 클릭 이벤트가 payload 안에 들어가지 않도록
    // () => undefined를 두 번째 파라미터로 넣어 줍니다.
    export const increaseAsync = createAction(INCREASE_ASYNC, () => undefined);
    export const decreaseAsync = createAction(DECREASE_ASYNC, () => undefined);
    
    function* increaseSaga() {
      yield delay(1000); // 1초를 기다립니다.
      yield put(increase()); // 특정 액션을 디스패치합니다.
    }
    
    function* decreaseSaga() {
      yield delay(1000); // 1초를 기다립니다.
      yield put(decrease()); // 특정 액션을 디스패치합니다.
    }
    
    export function* counterSaga() {
      // takeEvery 들어오는 모든 액션에 대해 특정 작업을 처리해 줍니다.
      yield takeEvery(INCREASE_ASYNC, increaseSaga);
      // takeLatest 기존에 진행 중이던 작업이 있다면 취소 처리하고
      // 가장 마지막으로 실행된 작업만 수행합니다.
      yield takeLatest(DECREASE_ASYNC, decreaseSaga);
    }
    const initialState = 0; // 상태는 꼭 객체일 필요가 없습니다. 숫자도 작동해요.
    
    const counter = handleActions(
      {
        [INCREASE]: state => state + 1,
        [DECREASE]: state => state - 1
      },
      initialState
    );
    
    export default counter;

    신간 소식 구독하기
    뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.