어떤가요? 중복되는 코드들이 많이 사라졌지요? 취향에 따라 이렇게 리팩토링하여 사용해도 되고, const를 세 번 사용하여 선언해도 상관없습니다.

    이제 createRequestSaga를 통해 각 API를 위한 사가를 생성하고, 액션 생성 함수와 리듀서도 구현해 보겠습니다.

    modules/auth.js

    import { createAction, handleActions } from 'redux-actions';
    import produce from 'immer';
    import { takeLatest } from 'redux-saga/effects';
    import createRequestSaga, {
      createRequestActionTypes,
    } from '../lib/createRequestSaga';
    import * as authAPI from '../lib/api/auth';
    
    const CHANGE_FIELD = 'auth/CHANGE_FIELD';
    const INITIALIZE_FORM = 'auth/INITIALIZE_FORM';
    
    const [REGISTER, REGISTER_SUCCESS, REGISTER_FAILURE] = createRequestActionTypes(
      'auth/REGISTER',
    );
    
    const [LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE] = createRequestActionTypes(
      'auth/LOGIN',
    );
    
    export const changeField = createAction(
      CHANGE_FIELD,
      ({ form, key, value }) => ({
        form, // register , login
        key, // username, password, passwordConfirm
        value, // 실제 바꾸려는 값
      }),
    );
    export const initializeForm = createAction(INITIALIZE_FORM, form => form); // register/login
    export const register = createAction(REGISTER, ({ username, password }) => ({
      username,
      password,
    }));
    export const login = createAction(LOGIN, ({ username, password }) => ({
      username,
      password,
    }));
    
    // 사가 생성
    const registerSaga = createRequestSaga(REGISTER, authAPI.register);
    const loginSaga = createRequestSaga(LOGIN, authAPI.login);
    export function* authSaga() {
      yield takeLatest(REGISTER, registerSaga);
      yield takeLatest(LOGIN, loginSaga);
    }
    
    const initialState = {
      register: {
        username: '',
        password: '',
        passwordConfirm: '',
      },
      login: {
        username: '',
        password: '',
      },
      auth: null,
      authError: null,
    };
    
    const auth = handleActions(
      {
        [CHANGE_FIELD]: (state, { payload: { form, key, value } }) =>
          produce(state, draft => {
            draft[form][key] = value; // 예: state.register.username을 바꾼다.
          }),
        [INITIALIZE_FORM]: (state, { payload: form }) => ({
          ...state,
          [form]: initialState[form],
          authError: null, //  전환  회원 인증 에러 초기화
        }),
        // 회원가입 성공
        [REGISTER_SUCCESS]: (state, { payload: auth }) => ({
          ...state,
          authError: null,
          auth,
        }),
        // 회원가입 실패
        [REGISTER_FAILURE]: (state, { payload: error }) => ({
          ...state,
          authError: error,
        }),
        // 로그인 성공
        [LOGIN_SUCCESS]: (state, { payload: auth }) => ({
          ...state,
          authError: null,
          auth,
        }),
        // 로그인 실패
        [LOGIN_FAILURE]: (state, { payload: error }) => ({
          ...state,
          authError: error,
        }),
      },
      initialState,
    );
    
    export default auth;

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