프론트엔드/React

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

chul.Lee 2022. 4. 19. 21:55
728x90

 

1. 미들웨어란?

 

리덕스 미들웨어는 액션을 디스패치하면  리듀서에서 이를 처리하기 이전에 사전 작업들을 실행합니다.

미들웨어는 이 떄 액션과 리듀서사이의 중간자 역할을 합니다.

 

 

 

 

리듀서가 액션을 처리하기 전에 미들웨어는 아래의 작업들을 수행할 수 있습니다.

  • 전달받은 액션을 콘솔에 기록
  • 전달받은 액션 정보를 기반으로 액션을 완전히 취소
  • 다른종류의 액션을 추가로 디스패치하기

 

1.1 미들웨어 만들기

 

src 디렉토리에 lib 디렉토리를 생성하고, 그 안에 loggerMiddleware.js 파일을 생성합니다.

 

 

- lib/loggerMiddleware.js

 

미들웨어는 아래와 같은 구조를 가지고 있습니다.

 


const loggerMiddleware = store => next => action => {
    //미들웨어 기본 구조
};

export default loggerMiddleware

 

위 코드의 리덕스 미들웨어 구조를 풀어서 function형식으로 작성하면 아래와 같은구조를 가지게 됩니다.

 

const loggerMiddleware = function loggerMiddleware(store) {
	return function(next) {
    	return function(action) {
        // 미들웨어 기본 구조
        }
    }
}

 

미들웨어는 함수를 반환하는 함수를 반환하는 "함수"입니다.

여기 함수에서 파리머터로 받아 오는 store는 리덕스 스토어 인스턴스를, action은 디스패치된 액션을 가리키고 있습니다.

 

next 파라미터는 함수형태를 가지고 있고 store, dispatch()와 비슷한 역할을 수행합니다.

 

단 한가지 차이점은 next(action)을 호출하면 다음 처리해야 할 미들웨어에게 액션을 넘겨주고, 만약 그다음 미들웨어가 따로 없다면 리듀서에게 액션을 넘겨준다는게 차이점입니다.

 

 

미들웨어 내부에서는 store, dispatch를 사용하면 첫 번쨰 미들웨부터 순차적으로 다시 처리하게 됩니다.

미들웨어에서 next를 사용하지 않느다면 액션이 리듀서에게 전달되지 않고 액션이 무시하게 됩니다.

 

이제는 미들웨어 안에 다음정보를 순차적으로 콘솔에 보여줍니다.

 

  1. 이전 상태 
  2. 액션 정보 
  3. 새로워진 형태

 

- lib/loggerMiddleware.js

 

const loggerMiddleware = store => next => action => {
    console.group(action && action.type); //액션 타입으로 로그를 그룹화
    console.log('이전 상태', store.getState());
    console.log('액션', action);
    next(action); //다음 미들웨어 혹은 미들웨어가 없으면 리듀서에게 전달됨
    console.log("다음 상태", store.getState()); //업데이트된 상태
    console.groupEnd()
};

export default loggerMiddleware

 

만든 리덕스 미들웨어를 이제 스토어에 적용할 차례입니다.

미들웨어는 스토어를 생성하는 과정에서 적용합니다.

 

 

 

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 loggerMiddleware from './lib/loggerMiddleware';

// 미들웨어 적용
const store = createStore(rootReducer, applyMiddleware(loggerMiddleware));

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.2 redux-logger 사용하기

 

이번에는 오픈소스로 사용되는 redux-logger 미들웨어를 설치하고 사용해볼 예정입니다.

 

먼저 redux-logger를 설치합니다.

 

yarn add redux-logger

 

 

그리고 index.js 파일을 아래와 같이 수정합니다.

 

 

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';

const logger = createLogger();
const store = createStore(rootReducer, applyMiddleware(logger));

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();

 

 

 

수정했으면 브라우저에서 다시 개발자도구를 확인해보세요.

 

이전콘솔화면 보다 색상도 추가되었고 디스패치에 시간도 추가 되었습니다.

 

이렇게 두가지 미들웨어를 사용해보니  완성된 라이브러리 미들웨어를 사용하는게 더 사용도 쉽고 편하게 사용할 수 있음을 알 수 있었습니다.

 

 

 

 

 

 

728x90