# typescript에 redux saga 추가하기 예제

# 사전 학습

# package.json 설치

yarn add redux-saga

# 파일 구조

폴더/파일명 설명
/src
ㅣㅡ /store reduce store
ㅣㅡㅡ /counter counter store
ㅣㅡㅡㅡ /action counter action 함수 모음
ㅣㅡㅡㅡ /reducer counter reducer 모음
ㅣㅡㅡㅡ /sagas counter saga 모음
ㅣㅡㅡㅡ /types counter types 모음

# types.ts

export const CHANGE_NUMBER = "CHANGE_NUMBER" as const;
export const CHANGE_NUMBER_SAGA_REQUEST = "CHANGE_NUMBER_SAGA_REQUEST" as const;
export const CHANGE_NUMBER_SAGA_SUCCESS = "CHANGE_NUMBER_SAGA_SUCCESS" as const;
export const CHANGE_NUMBER_SAGA_FAILURE = "CHANGE_NUMBER_SAGA_FAILURE" as const;

export type counterProps = {
  count: number;
  loading: false;
};

# actions.ts

import {
  CHANGE_NUMBER,
  CHANGE_NUMBER_SAGA_REQUEST,
  CHANGE_NUMBER_SAGA_SUCCESS,
  CHANGE_NUMBER_SAGA_FAILURE
} from "store/counter/types/";

export const changeNumber = (number: number) => ({
  type: CHANGE_NUMBER,
  payload: { data: number }
});

export const changeNumberRequest = () => ({
  type: CHANGE_NUMBER_SAGA_REQUEST
});

export const changeNumberSuccess = (number: number) => ({
  type: CHANGE_NUMBER_SAGA_SUCCESS,
  payload: { data: number }
});

export const changeNumberFailure = () => ({
  type: CHANGE_NUMBER_SAGA_FAILURE
});

export type ActionRequest =
  | ReturnType<typeof changeNumber>
  | ReturnType<typeof changeNumberSuccess>
  | ReturnType<typeof changeNumberFailure>;

# reducer.ts

import produce from "immer";
import {
  CHANGE_NUMBER,
  CHANGE_NUMBER_SAGA_REQUEST,
  CHANGE_NUMBER_SAGA_SUCCESS,
  CHANGE_NUMBER_SAGA_FAILURE,
  counterProps
} from "store/counter/types";
import { ActionRequest } from "store/counter/actions";

export const initalState: counterProps = {
  count: 0,
  loading: false
};

export const counter = (
  state: counterProps = initalState,
  action: ActionRequest
) =>
  produce(state, draft => {
    switch (action.type) {
      case CHANGE_NUMBER:
        draft.count = action.payload.data;
        break;
      case CHANGE_NUMBER_SAGA_REQUEST:
        draft.loading = true;
        break;
      case CHANGE_NUMBER_SAGA_SUCCESS:
        draft.loading = false;
        draft.count = action.payload.data;
        break;
      case CHANGE_NUMBER_SAGA_FAILURE:
        draft.loading = false;
        draft.count = 0;
        break;
      default:
        return state;
    }
  });

# sagas.ts

import { all, fork, put, call, takeLatest } from "redux-saga/effects";
import { AxiosResponse } from "axios";
import { CHANGE_NUMBER_SAGA_REQUEST } from "store/counter/types";
import {
  changeNumberSuccess,
  changeNumberFailure
} from "store/counter/actions";

function* changeCountSaga() {
  try {
    const result: AxiosResponse<{ count: number }> = yield call(
      $api.changeCounter
    );
    yield put(changeNumberSuccess(result.count));
  } catch (err) {
    yield put(changeNumberFailure());
  }
}

function* watchChangeCount() {
  yield takeLatest(CHANGE_NUMBER_SAGA_REQUEST, changeCountSaga);
}

export default function* counterSaga() {
  yield all([fork(watchChangeCount)]);
}
Last Updated: 3/24/2021, 8:55:12 PM