Next.js

React에서 Redux, Reducer, 그리고 Redux-Saga를 활용한 상태 관리(Redux-DevTools)

code2772 2024. 7. 28. 15:53
728x90
반응형

리액트 애플리케이션을 개발하다 보면 상태 관리가 복잡해지는 경우가 많습니다. 이런 상황에서 상태 관리를 보다 체계적으로 관리하기 위해 Redux를 사용할 수 있습니다. 또한, 비동기 작업을 효율적으로 처리하기 위해 Redux-Saga를 활용할 수 있습니다. 이번 글에서는 리덕스(Redux), 리듀서(Reducer), 사가(Saga)에 대해 자세히 알아보겠습니다.

 

 

1. Redux란?

Redux는 애플리케이션의 상태를 중앙에서 관리하는 라이브러리입니다. Redux는 상태를 예측 가능하게 관리하며, 다양한 컴포넌트 간에 데이터를 쉽게 공유할 수 있도록 돕습니다.

Redux의 주요 개념은 다음과 같습니다:

  • 스토어(Store): 애플리케이션의 상태를 담고 있는 객체입니다.
  • 액션(Action): 상태에 변화를 일으키는 객체입니다. 액션은 타입(type)과 페이로드(payload)를 가집니다.
  • 리듀서(Reducer): 현재 상태와 액션을 받아 새로운 상태를 반환하는 순수 함수입니다.
  • 디스패치(Dispatch): 액션을 스토어에 전달하는 함수입니다.
dispatch는 Redux에서 액션을 발생시키는 함수입니다. 액션은 상태 변경을 위한 지시사항이라고 볼 수 있습니다. 위 코드에서는 직접적으로 보이지 않지만, 컴포넌트에서 다음과 같이 사용될 것입니다:

 

dispatch(fetchCallbacksRequest({ page: 1, size: 20 }));

 

2. 리듀서(Reducer)란?

리듀서는 Redux에서 상태 변화를 처리하는 순수 함수입니다. 현재 상태와 액션을 받아서 새로운 상태를 반환합니다.

아래는 createSlice를 사용한 리듀서 예제입니다:

 

// 콜백 상태를 위한 인터페이스 정의
interface CallbackState {
  isCallbackLoading: boolean;  // 콜백 데이터 로딩 중 여부
  isCallbackSuccess: boolean;  // 콜백 데이터 로드 성공 여부
  isCallbackError: boolean;    // 콜백 데이터 로드 실패 여부
  isDeletingCallback: boolean; // 콜백 삭제 중 여부
                /*
                생략
                */
  };
}

// 초기 상태 정의
const initialState: CallbackState = {
  // ... (초기값 설정)
};

// 콜백 관련 리듀서 정의
const callbackSlice = createSlice({
  name: "callback",
  initialState,
  reducers: {
    // 콜백 데이터 요청 액션
    fetchCallbacksRequest: (state, action: PayloadAction<{ page: number, size: number }>) => {
      state.isCallbackLoading = true;
      // ... (상태 업데이트)
    },
    // 콜백 데이터 요청 성공 액션
    fetchCallbacksSuccess: (state, action: PayloadAction<any>) => {
      state.isCallbackLoading = false;
      state.callbackData = action.payload;
      // ... (상태 업데이트)
    },
    // 콜백 데이터 요청 실패 액션
    fetchCallbacksError: (state, action: PayloadAction<string>) => {
      state.isCallbackLoading = false;
      state.error = action.payload;
      // ... (상태 업데이트)
    },
    // 콜백 상태 초기화 액션
    resetCallbackState: (state) => {
      // ... (상태 초기화)
    },
    // 콜백 삭제 요청 액션
    deleteCallbackRequest: (state, action: PayloadAction<any[]>) => {
      state.isDeletingCallback = true;
      // ... (상태 업데이트)
    },
    // 콜백 삭제 성공 액션
    deleteCallbackSuccess: (state) => {
      state.isDeletingCallback = false;
      // ... (상태 업데이트)
    },
    // 콜백 삭제 실패 액션
    deleteCallbackError: (state, action: PayloadAction<string>) => {
      state.isDeletingCallback = false;
      state.deleteCallbackError = action.payload;
    },
  },
});

// 액션 생성자 내보내기
export const { 
  fetchCallbacksRequest, 
  fetchCallbacksSuccess, 
  fetchCallbacksError,
  resetCallbackState,
  deleteCallbackError,
  deleteCallbackRequest,
  deleteCallbackSuccess
} = callbackSlice.actions;

 

위 코드에서 callbackSlice는 상태와 액션을 정의하고, 리듀서 함수를 자동으로 생성합니다. 각 액션에 대응하는 상태 변화를 관리합니다.


3. Redux-Saga란?

Redux-Saga는 Redux 애플리케이션에서 비동기 작업을 처리하기 위한 미들웨어입니다. Redux-Saga는 제너레이터 함수를 사용하여 비동기 작업을 효율적으로 관리할 수 있게 해줍니다.

Saga의 주요 개념은 다음과 같습니다:

  • 사가(Saga): 제너레이터 함수로 작성된 비동기 작업 처리 함수입니다.
  • 이펙트(Effect): 사가 내부에서 발생하는 비동기 작업입니다. 예를 들어 call, put 등이 있습니다.
  • takeEvery: 특정 액션 타입에 대해 모든 액션을 처리합니다.
  • takeLatest: 특정 액션 타입에 대해 마지막 액션만 처리합니다.

아래는 Redux-Saga의 예제입니다:

 

import { call, put, takeLatest } from 'redux-saga/effects';
import { 
  fetchCallbacksRequest, 
  fetchCallbacksSuccess, 
  fetchCallbacksError, 
  deleteCallbackError, 
  deleteCallbackRequest, 
  deleteCallbackSuccess 
} from '../reducers/callback';
import api from './axiosInstance';

// 콜백 데이터를 가져오는 API 호출 함수
const fetchCallbacksAPI = (page: number, size: number) => {
  return api.get(`/user/callback?page=${page}&size=${size}`);
}

// fetchCallbacksRequest 액션에 대응하는 사가 함수
function* handleFetchCallbacks(action: ReturnType<typeof fetchCallbacksRequest>) {
  try {
    const { page, size } = action.payload;
    console.log('Fetching callbacks...', { page, size });
    const result = yield call(fetchCallbacksAPI, page, size); // API 호출
    console.log('API response:', result);
    yield put(fetchCallbacksSuccess(result.data)); // 성공 액션 디스패치
  } catch (error) {
    console.error('Error fetching callbacks:', error);
    yield put(fetchCallbacksError(error.response?.data?.message || 'An error occurred while fetching callbacks')); // 실패 액션 디스패치
  }
}

// 콜백 데이터를 삭제하는 API 호출 함수
const deleteCallbacksAPI = (callbackIds: any[]) => {
  return api.post('/user/callback/delete', callbackIds);
}

// deleteCallbackRequest 액션에 대응하는 사가 함수
function* handleDeleteCallbacks(action: ReturnType<typeof deleteCallbackRequest>) {
  try {
    yield call(deleteCallbacksAPI, action.payload); // API 호출
    yield put(deleteCallbackSuccess()); // 성공 액션 디스패치
    // 삭제 후 목록 새로고침
    yield put(fetchCallbacksRequest({ page: 0, size: 20 }));
  } catch (error) {
    yield put(deleteCallbackError(error.response?.data?.message || 'An error occurred while deleting callbacks')); // 실패 액션 디스패치
  }
}

// 루트 사가
export default function* callbackSaga() {
  yield takeLatest(fetchCallbacksRequest.type, handleFetchCallbacks); // 최신 fetchCallbacksRequest 액션만 처리
  yield takeLatest(deleteCallbackRequest.type, handleDeleteCallbacks); // 최신 deleteCallbackRequest 액션만 처리
}

 

위 코드에서 handleFetchCallbacks와 handleDeleteCallbacks 사가는 비동기 작업(API 호출)을 처리합니다. takeLatest를 사용하여 최신 액션만 처리하도록 설정했습니다.


4. Redux와 Saga의 통합

리덕스와 사가를 통합하여 사용하려면 redux-saga 미들웨어를 설정해야 합니다. 기본적인 설정 과정은 다음과 같습니다:

 

import { configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import callbackReducer from './reducers/callback';
import callbackSaga from './sagas/callback';

// 사가 미들웨어 생성
const sagaMiddleware = createSagaMiddleware();

// 스토어 설정
const store = configureStore({
  reducer: {
    callback: callbackReducer, // 콜백 리듀서 등록
  },
  middleware: [sagaMiddleware], // 사가 미들웨어 적용
});

// 사가 실행
sagaMiddleware.run(callbackSaga);

export default store;

 

위 코드에서 configureStore를 사용하여 스토어를 설정하고, createSagaMiddleware로 사가 미들웨어를 생성하여 스토어에 적용합니다. 그런 다음 sagaMiddleware.run을 호출하여 루트 사가를 실행합니다.


이렇게 Redux와 Redux-Saga를 사용하여 React 애플리케이션에서 상태 관리와 비동기 작업을 효율적으로 처리할 수 있습니다. 이를 통해 코드의 가독성과 유지보수성을 높이고, 애플리케이션의 상태를 보다 체계적으로 관리할 수 있습니다.

 

Redux DevTools

 Redux 애플리케이션의 상태를 모니터링하고 디버깅하기 위한 도구입니다. Redux는 애플리케이션 상태를 예측 가능하게 관리하기 위한 상태 관리 라이브러리이며, Redux DevTools는 이를 더 효과적으로 사용하고 디버깅하는 데 도움을 줍니다

 

 

상태를 한번에 확인이 가능하며 

 

 

어떤 것들을 작성했는지도 한번에 알 수 있는 편리한 도구이다.

반응형