Immer를 사용하여 비동기 상태 관리하기

이번 글에서는 Immer 라이브러리를 사용하여 비동기 상태 관리를 어떻게 처리할 수 있는지 알아보겠습니다. Immer는 JavaScript에서 불변성을 유지하는 상태 관리를 도와주는 편리한 도구입니다.

Immer란?

Immer는 Immutable.js와 같은 라이브러리와 달리, Immutable Data Structure을 생성하지 않고 Immutable Data Updating을 가능하게 해줍니다. 이를 통해 코드의 가독성을 높이고 복잡한 상태 관리 로직을 관리하기 쉬워집니다.

Immer를 사용하여 비동기 상태를 관리하는 방법은 다음과 같습니다:

  1. Draft State 생성하기: Immer는 draft state 라고 불리는 수정 가능한 가상의 상태를 생성합니다. 이 draft state는 실제 상태와는 별도로 관리되며, 상태를 업데이트할 때 사용됩니다.

  2. Draft State를 수정하기: 생성된 draft state를 수정하여 비동기 작업에서 발생한 상태 변화를 처리합니다. Immer는 draft state를 변경하는 모든 작업을 추적하고, 이를 실제 상태에 반영하기 위해 필요한 최소한의 변경을 수행합니다.

  3. Draft State를 실제 상태에 반영하기: Immer는 draft state에서 발생한 변경 사항을 실제 상태에 반영합니다. 변경된 상태는 앱의 상태 관리 로직에 따라 리렌더링되거나, 다른 작업에 사용될 수 있습니다.

예제 코드

다음은 Immer를 사용하여 비동기 상태를 관리하는 간단한 예제 코드입니다. 이 예제 코드는 Redux를 기반으로 작성되었으며, redux-thunk 미들웨어를 사용하여 비동기 작업을 처리합니다.

import produce from 'immer';

// 초기 상태 정의
const initialState = {
  loading: false,
  data: null,
  error: null,
};

// 액션 타입 정의
const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST';
const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';

// 액션 생성자 함수 정의
export const fetchDataRequest = () => ({ type: FETCH_DATA_REQUEST });
export const fetchDataSuccess = (data) => ({ type: FETCH_DATA_SUCCESS, payload: data });
export const fetchDataFailure = (error) => ({ type: FETCH_DATA_FAILURE, payload: error });

// 리듀서 함수
const reducer = (state = initialState, action) => {
  return produce(state, (draft) => {
    switch (action.type) {
      case FETCH_DATA_REQUEST:
        draft.loading = true;
        draft.error = null;
        break;
      case FETCH_DATA_SUCCESS:
        draft.loading = false;
        draft.data = action.payload;
        break;
      case FETCH_DATA_FAILURE:
        draft.loading = false;
        draft.error = action.payload;
        break;
      default:
        break;
    }
  });
};

// 비동기 액션 처리
export const fetchData = () => {
  return (dispatch) => {
    dispatch(fetchDataRequest());

    // 비동기 작업 처리
    fetch('https://api.example.com/data')
      .then((response) => response.json())
      .then((data) => {
        dispatch(fetchDataSuccess(data));
      })
      .catch((error) => {
        dispatch(fetchDataFailure(error));
      });
  };
};

위의 예제 코드에서는 Immer를 사용하여 draft state를 생성하고, draft state를 수정하여 상태 변화를 처리합니다. 이를 통해 불필요한 상태 복제를 피하고, 코드의 가독성을 향상시킬 수 있습니다.

마무리

Immer를 사용하면 비동기 상태 관리를 더 쉽게 처리할 수 있습니다. 이를 통해 코드의 복잡성을 줄이고, 상태 관리를 더욱 관리하기 쉽게 만들 수 있습니다. Immer는 Redux와 같은 상태 관리 라이브러리와 호환되기 때문에, 기존 프로젝트에 적용하기 쉽습니다.

#Immer #비동기상태관리