어떤가요? 중복되는 코드들이 많이 사라졌지요? 취향에 따라 이렇게 리팩토링하여 사용해도 되고, 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;