18.3.2.2 비동기 카운터 만들기
기존에 thunk 함수로 구현했던 비동기 카운터를 이번에는 redux-saga를 사용하여 구현해 봅시다. 우선 라이브러리를 설치해 주세요.
$ yarn add redux-saga
그리고 counter 리덕스 모듈을 열어서 기존 thunk 함수를 제거하고, INCREMENT_ASYNC와 DECREMENT_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;