Redux Thunk를 사용한 비동기 API 호출 예제

Redux는 JavaScript 애플리케이션의 상태 관리를 용이하게 해주는 라이브러리입니다. Redux Thunk는 Redux 미들웨어 중 하나로, 비동기 작업을 처리하기 위해 사용됩니다. 이번 예제에서는 Redux Thunk를 사용하여 API 호출을 비동기적으로 처리하는 방법에 대해 알아보겠습니다.

설치

먼저, Redux Thunk를 설치해야 합니다. 아래 명령어를 사용하여 의존성을 추가하세요.

npm install redux-thunk

설정

Redux Thunk를 Redux 스토어에 추가하기 위해, Redux createStore 함수를 사용할 때 applyMiddleware 함수를 사용합니다. 아래는 Redux Thunk를 추가한 Redux 스토어를 만드는 예제입니다.

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

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

액션 생성자와 API 호출

Redux Thunk를 사용하여 비동기 API 호출을 처리하기 위해서는, 액션 생성자에서 비동기 작업을 수행하는 함수를 정의해야 합니다. 아래는 Redux Thunk를 사용하여 비동기 API 호출을 처리하는 예제입니다.

import axios from 'axios';

// 액션 타입 정의
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 fetchData = () => {
  return dispatch => {
    dispatch({ type: FETCH_DATA_REQUEST });

    axios.get('https://api.example.com/data')
      .then(response => {
        dispatch({
          type: FETCH_DATA_SUCCESS,
          payload: response.data
        });
      })
      .catch(error => {
        dispatch({
          type: FETCH_DATA_FAILURE,
          error: error.message
        });
      });
  };
};

위 예제에서는 axios 모듈을 사용하여 비동기 API 호출을 수행하고, 호출이 성공했을 때와 실패했을 때에 따라 액션을 디스패치합니다.

리듀서

API 호출의 결과를 처리하기 위해 리듀서를 수정해야 합니다. 아래는 API 호출 결과를 처리하는 리듀서의 예제입니다.

import { combineReducers } from 'redux';

// 액션 타입 임포트

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

// 데이터 리듀서
const dataReducer = (state = initialState, action) => {
  switch(action.type) {
    case FETCH_DATA_REQUEST:
      return {
        ...state,
        loading: true,
        error: null
      };
    case FETCH_DATA_SUCCESS:
      return {
        ...state,
        loading: false,
        data: action.payload
      };
    case FETCH_DATA_FAILURE:
      return {
        ...state,
        loading: false,
        error: action.error
      };
    default:
      return state;
  }
};

// 루트 리듀서
const rootReducer = combineReducers({
  data: dataReducer
});

export default rootReducer;

위 예제에서는 FETCH_DATA_REQUEST, FETCH_DATA_SUCCESS, FETCH_DATA_FAILURE 액션을 처리하는 리듀서를 작성하였습니다. API 호출이 시작될 때는 로딩 상태를 true로 변경하고, 호출이 성공하면 로딩 상태를 false로 변경하고 데이터를 업데이트합니다. 호출이 실패하면 에러 메시지를 저장합니다.

컴포넌트에서 API 호출

마지막으로, API 호출을 수행할 컴포넌트에서 액션 생성자를 디스패치하여 API를 호출합니다. 아래는 컴포넌트에서 API 호출을 수행하는 예제입니다.

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchData } from './actions';

const DataComponent = () => {
  const dispatch = useDispatch();
  const data = useSelector(state => state.data.data);
  const loading = useSelector(state => state.data.loading);

  useEffect(() => {
    dispatch(fetchData());
  }, [dispatch]);

  if (loading) {
    return <div>Loading...</div>
  }

  if (data) {
    return <div>{data}</div>
  }

  return <div>Error occurred</div>;
};

export default DataComponent;

위 예제에서는 useEffect 훅을 사용하여 컴포넌트가 마운트될 때 fetchData 액션을 디스패치합니다. 데이터가 로딩 중인 동안에는 “Loading…“을, 데이터가 있을 경우에는 데이터를 출력하고, 에러가 발생한 경우에는 “Error occurred”를 표시합니다.

결론

Redux Thunk는 Redux를 사용하여 비동기 작업을 처리할 때 유용한 미들웨어입니다. 위 예제를 참고하여 Redux Thunk를 사용하여 API 호출을 비동기적으로 처리해보세요.

참고 자료