프론트엔드/React

[프론트엔드] 리덕스 미들웨어를 통한 비동기 작업 관리[4]

chul.Lee 2022. 4. 19. 23:06
728x90

 

1. 비동기 작업을 처리하는 미들웨어 사용

 

이전 시간에는  리덕스 미들웨어의 동작구조를 알아보았습니다.

 

이번에는 오픈소스 커뮤니티에 공개된 미들웨어 라이브러를 사용하여 리덕스 프로젝트에서

비동기 처리작업을 더욱 효율적으로 관리해 보겠습니다.

 

비동기 작업을 처리할 떄 도움을 주는 미들웨어는 다양한 종류가 있습니다. 이번에 사용할 미들웨어는 다음과 같습니다.

 

  • redux-thunk : 비동기 작업을 처리할 떄 가장 많이 사용되는 미들웨어 라이브러리 입니다. 객체가 아닌 함수 형태의 액션을 디스패치 할 수 있도록 도와주는 역할을 합니다.
  • reudx-saga : redux-thunk 다음으로 많이 사용되는 비동기 작업 미들웨어 라이브러리입니다. 특정 액션이 디스패치되었을 떄 정해진 로직에 따라 다른 액션을 디스패치시키는 규칙을 작성하여 비동기 작업을 처리할 수 있도록 도와줍니다.

 

 

1.1 redux-thunk 

 

redux-thunk는 리덕스를 사용하는 프로젝트에서 비동기 작업을 처리할 떄 가장 기본적으로 사용하는 미들웨어입니다.

리덕스 창지가 댄 아프라모프가 만들었으며ㅡ 리덕스 공식 메뉴얼에서 해당 미들웨어를 사용하는 예시를 보여주고 있습니다.

 

 

1.1.1 Thunk란?

 

Thunk는 특정 작업을 나중에 할 수 있도록 미루기 위해 함수 형태로 감싼다는 것을 의미합니다.

 

redux-thunk 라이브러리를 사용하면 thunk 함수를 만들어서 디스패치를 걸 수 있습니다.

그러면 리덕스 미들웨어가 thunk 함수를 전달받아 store의 dispatch를 파라미터로 넣고 호출해 줍니다.

 

아래는 redux-thunk 에서 사용하는 thunk 함수의 예시입니다.

 

const sampleThunk = () => (dispatch, getState) => {
	// 현재 상태를 참조
	// 새 액션을 디스패치
}

 

 

1.1.2 미들웨어 적용하기

 

redux-thunk 미들웨어를 설치하고 프로젝트에 적용해 보겠습니다.

다음영령어로 먼저 라이브러리를 설치합니다.

 

yarn add redux-thunk

 

설치했으면 아래의 index,js 파일에서 스토어의 thunk를 적용 해보세요. 

 

 

- index.js

 

import React from 'react';
import ReactDOM from 'react-dom';
import { applyMiddleware, createStore } from 'redux';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import rootReducer from './modules';
import { createLogger } from 'redux-logger';
import ReduxThunk from 'redux-thunk'

const logger = createLogger();
// redux-thunk 적용
const store = createStore(rootReducer, applyMiddleware(logger, ReduxThunk));

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

1.1.3 Thunk 생성 함수 만들기

 

redux-thunk는 액션 생성 함수에서 일반 액션 객체를 반환하는 대신의 함수를 반환합니다.

increaseASync와 decreaseAsync 함수를 만들어 카운터 값을 비동기적으로 변경해 보겠습니다.

 

 

- modules/counter.js

 

import { createAction, handleActions } from "redux-actions";

const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';

export const increase = createAction(INCREASE);
export const decrease = createAction(DECREASE);

// 1초 뒤에 increase 혹은 decrease 함수를 디스패치함
export const increaseAsync = () => dispatch => {
        setTimeout(() => {
            dispatch(increase())
        }, 1000)
}

export const decreaseAsync = () => dispatch => {
    setTimeout(() => {
        dispatch(decrease());
    }, 1000);
};

const initalState = 0; //객체값이 아닌 숫자도 잘 작동합니다.

const counter = handleActions(
    {
        [INCREASE]: state => state + 1,
        [DECREASE]: state => state - 1
    },
    initalState
);

export default counter

 

 

- container/CounterContainer.js

 

import React from "react";
import { connect } from "react-redux";
import { increaseAsync, decreaseAsync } from '../modules/counter'
import Counter from "../components/Counter";

const CounterContainer = ({ number, increaseAsync, decreaseAsync }) => {
    return (
        <Counter
        number={number}
        onIncrease={increaseAsync}
        onDecrease={decreaseAsync}
        />
    );
};

export default connect(
    (state) => ({
        number: state.counter,
    }),
    {
        increaseAsync,
        decreaseAsync,
    }
)(CounterContainer);

 

 

코드를 작성하셨으면 브라우저에서 버튼을 클릭해보세요.

숫자가 1초 뒤에 변경됩니다.

 

개발자도구에서 발생한 액션 기록도 같이 확인해 보세요.

 

 

 

 

728x90