티스토리 뷰

반응형

Redux Thunk는 미들웨어 중 하나로, 비동기 작업을 처리하고 액션을 디스패치할 수 있게 도와주는 라이브러리다. 리덕스는 동기적인 작업에 특화되어 있어서, 비동기 작업을 처리하기 위해서는 Thunk와 같은 미들웨어가 필요하다. 그 외에도 비동기 작업을 처리하는 미들웨어로 Redux Saga, Redux Observable 등이 있다.

 

동기적 액션 생성자와 Thunk를 사용한 비동기 액션 생성자 비교

동기적 액션 생성자

  • 액션 함수는 단순히 액션 ‘객체’를 반환
  • 반환 형식: { type: '액션_타입', payload: '데이터' }
  • 동기적인 액션을 생성하는 역할

Thunk를 사용한 비동기 액션 생성자

  • 비동기 액션 함수는 ‘함수’를 반환
  • 비동기 액션 함수는 dispatch를 인자로 받음
    이를 통해 함수 내부에서 다른 액션을 디스패치할 수 있는 권한을 갖게 되는 것
  • 비동기 코드 실행 전, 실행 후 등 비동기 동작 전 후 상황에서 액션을 실행해야 할 때 디스패치를 사용
  • 비동기 액션 함수 내에서 비동기 작업을 수행하고, 필요에 따라 여러 액션을 디스패치할 수 있음
  • 반환 형식: (dispatch) => { /* 비동기 작업 수행 및 액션 디스패치 */ }

 

redux-thunk 설치와 코드 예제

설치

npm install redux-thunk

 

코드 예제

github: https://github.com/fromnowwon/redux-cafe-order-system

 

store.js

import { createStore, applyMiddleware } from "redux";
import rootReducer from "./rootReducer";
import logger from "redux-logger";
import { thunk } from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";

// 여러 middleware 배열로 관리
// thunk를 먼저 배치
const middleware = [thunk, logger];

// rootReducer를 사용하는 스토어 생성
const store = createStore(
    rootReducer,
    composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

 

rootReducer.js

import { combineReducers } from "redux";
import orderReducer from "./order/reducer";
import customerReducer from "./customer/reducer";

// 모든 리듀서 통합
const rootReducer = combineReducers({
    orders: orderReducer,
    customers: customerReducer,
});

export default rootReducer;

 

reducer.js

import {
    FETCH_CUSTOMER_REQUEST,
    FETCH_CUSTOMER_SUCCESS,
    FETCH_CUSTOMER_FAILURE,
} from "./types";

const initialState = {
    items: [],
    loading: false,
    error: null,
};

const customerReducer = (state = initialState, action) => {
    switch (action.type) {
        case FETCH_CUSTOMER_REQUEST:
            return {
                ...state,
                loading: true,
            };
        case FETCH_CUSTOMER_SUCCESS:
            return {
                ...state,
                items: action.payload,
                loading: false,
            };
        case FETCH_CUSTOMER_FAILURE:
            return {
                ...state,
                error: action.payload,
                loading: false,
            };
        default:
            return state;
    }
};

export default customerReducer;

 

actions.js

import {
  FETCH_CUSTOMER_REQUEST,
  FETCH_CUSTOMER_SUCCESS,
  FETCH_CUSTOMER_FAILURE,
} from "./types";

// 동기적인 액션 생성자: 데이터를 받아오는 요청이 시작됐음을 알리는 경우
export const fetchCustomerRequest = () => {
  return {
    type: FETCH_CUSTOMER_REQUEST,
  };
};

// 동기적인 액션 생성자: 데이터를 성공적으로 받아온 경우
export const fetchCustomerSuccess = (customers) => {
  return {
    type: FETCH_CUSTOMER_SUCCESS,
    payload: customers,
  };
};

// 동기적인 액션 생성자: 데이터를 받아오는 과정에서 에러가 발생한 경우
export const fetchCustomerFailure = (err) => {
  return {
    type: FETCH_CUSTOMER_FAILURE,
    payload: err,
  };
};

// Thunk를 사용한 비동기 액션 생성자
export const fetchCustomer = () => {
    // dispatch를 인자로 받는다
    return async (dispatch) => {
        try {
            // 먼저 요청이 시작했음을 나타내는 액션 디스패치
            dispatch(fetchCustomerRequest());

            // 비동기 작업
            const response = await fetch(
                "<https://jsonplaceholder.typicode.com/users>"
            );
            const customers = await response.json();

            // 비동기 작업 완료 후 성공 시 액션 디스패치
            dispatch(fetchCustomerSuccess(customers));
        } catch (error) {
            // 비동기 작업 실패 시 액션 디스패치
            dispatch(fetchCustomerFailure(error.message));
        }
    };
};
반응형
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31