리덕스 미들웨어(Redux middleware)

Jean Young Park·2023년 3월 7일
0

react

목록 보기
15/32

리덕스 미들웨어란? (Redux middleware)

Redux 미들웨어는 Redux Store와 액션 dispatch 사이에 위치하여 액션을 가로채고, 액션이 리듀서에 도달하기 전에 추가적인 작업을 수행할 수 있도록 도와주는 기능이다.
로깅, 충돌 보고, 비동기 API와 통신, 라우팅 등을 위해 Redux 미들웨어를 사용한다.

Redux 미들웨어를 사용하기 위해서는 applyMiddleware 함수를 사용해야한다. 이 함수는 createStore 함수에 인자로 전달되며, 미들웨어 함수들을 조합하여 새로운 함수 체인을 생성한다.

Redux Thunk

리덕스 미들웨어의 하나로, 액션 객체 대신 함수를 디스패치할 수 있게 해준다.이 함수는 디스패치와 getState 함수를 인자로 받아서, 비동기 작업을 처리하거나 여러 개의 액션을 디스패치할 수 있다.

일반적으로, 액션 생성자 함수는 단순한 객체를 반환하지만 Redux Thunk를 사용하면, 비동기적인 작업을 처리하고 나서 액션 객체를 반환하는 함수를 작성할 수 있다.

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

export default store;

applyMiddleware 함수를 사용하여 thunk 미들웨어를 적용하고, 이를 createStore 함수의 두 번째 인자로 전달하여 스토어를 생성한다.
아래는 redux-think 미들웨어를 이용한 thunk 함수를 사용한 예시이다.

// 액션 타입
export const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST';
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
export 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,
});

// thunk 함수
export const fetchData = () => {
  return (dispatch) => {
    dispatch(fetchDataRequest());
    fetch('https://example.com/data')
      .then(response => response.json())
      .then(data => dispatch(fetchDataSuccess(data)))
      .catch(error => dispatch(fetchDataFailure(error)));
  };
};

// 리듀서
const initialState = {
  loading: false,
  data: null,
  error: null,
};

const dataReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_DATA_REQUEST:
      return {
        ...state,
        loading: true,
      };
    case FETCH_DATA_SUCCESS:
      return {
        ...state,
        loading: false,
        data: action.payload,
      };
    case FETCH_DATA_FAILURE:
      return {
        ...state,
        loading: false,
        error: action.payload,
      };
    default:
      return state;
  }
};

리덕스 툴킷(Redux Toolkit)

리덕스 툴킷은 리덕스에서 개발자들이 더 쉽게 상태 관리를 할 수 있도록 도와주는 오픈소스 라이브러리이다.

리덕스를 사용하다 보면 반복적인 코드 작성, 불필요한 보일러플레이트 코드 작성, 불변성 유지에 대한 관리 등 여러 가지 불편함이 있다. 이러한 문제를 해결하기 위해 리덕스 툴킷이 나오게 되었다.

리덕스 툴킷은 다음과 같은 기능을 제공한다.

  • 불변성을 유지하기 위해 Immer 라이브러리를 내장하고 있다.

    Immer 라이브러리란?
    불변성 유지를 도와주는 JavaSceipr 라이브러리 중 하나이다. Immer를 사용하면 불변성 유지를 위해 번거로운 작업을 수행하지 않아도 되며, 간결하고 직관적인 코드 작성이 가능하다.
    Immer는 새로운 객체를 생성하는 대신, 기존 객체를 수정하여 새로운 버전을 생성하는 방식으로 불변성을 유지한다.

  • createSlice를 이용한 간단한 리듀서 생성이 가능하다.
  • Redux Dev Tools Extension을 내장하고 있다.
  • configureStore를 통해 store 생성 및 미들웨어 설정이 간편해진다.
  • thunk와 같은 비동기 작업을 처리하는 미들웨어인 createAsyncThunk와 createSlice의 extraReducers를 이용한 비동기 상태 관리가 가능하다.

예시

import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment(state) {
      state.value++;
    },
    decrement(state) {
      state.value--;
    },
    reset(state) {
      state.value = 0;
    },
    incrementByAmount(state, action) {
      state.value += action.payload;
    },
  },
});

const store = configureStore({
  reducer: counterSlice.reducer,
});

export const {
  increment,
  decrement,
  reset,
  incrementByAmount,
} = counterSlice.actions;

export default store;

위 예시 코드에서는 createSlice()함수를 사용하여 슬라이스를 정의하고, configueStore()함수를 사용하여 스토어를 생성합니다. 그리고, createSlice()함수에서 생성된 액션 생성자 함수들을 바로 내보낸다.

툴킷을 사용하면, 일반적인 리덕스 코드보다 코드량을 대폭 줄일 수 있다. 특히, createSlice()함수를 사용하면, 액션 타입, 액션 생성자 함수, 리듀서 함수를 한 번에 정의할 수 있다. 또한, configureStore()함수를 사용하면, 미들웨어 및 DevTools 연동 등의 작섭을 더욱 간단하게 처리할 수 있다.

0개의 댓글