[React다루는기술] 21. Redux Middleware 기본 구조 및 설명
in React on React 다루는 기술
Redux Middleware 기본 구조 및 설명에 대한 포스팅이다.
1. 미들웨어 기본 구조
미들웨어 기본 구조는 함수를 반환하는 함수를 반환하는 함수 개념이다.
loggerMiddleWare.js
const loggerMiddleWare = function loggerMiddleWare(store) {
//store: 리덕스 스토어 인스터스
return function (next) {
//next: 파라미터 함수
return function (action) {
//action: 디스패치 된 액션
};
};
};
export default loggerMiddleWare;
2. next() 함수
주어진 코드는 Redux 미들웨어의 예시로, Redux 스토어에 적용되는 로깅 미들웨어다.
여기서 next
함수는 미들웨어 체인 내에서 현재 미들웨어가 다음에 호출될 미들웨어를 호출하는 함수입니다. 미들웨어는 Redux 스토어에 적용되는 함수이며, 스토어로 들어오는 각각의 액션을 가로채어 특정 작업을 수행할 수 있습니다. 이때 next
함수를 호출하여 액션을 다음 미들웨어로 전달하거나 리듀서로 전달한다..
next
함수는 현재 미들웨어가 다음으로 호출될 미들웨어를 가리키는 함수입니다. 이 함수를 호출하면 다음으로 호출될 미들웨어가 실행됩니다. 만약 현재 미들웨어가 마지막이라면, next
함수를 호출하면 리듀서가 호출된다.
미들웨어는 일반적으로 다음과 같은 순서로 실행된다.:
- 액션이 디스패치되면, Redux 스토어에 적용된 미들웨어 체인이 실행된다.
- 각 미들웨어는 액션을 가로채어 원하는 작업을 수행하고,
next
함수를 호출하여 다음 미들웨어에게 액션을 전달한다. - 마지막으로 리듀서가 호출되어 새로운 상태가 반환된다.
next
함수를 호출함으로써 현재 미들웨어는 다음 미들웨어나 리듀서로 제어를 넘길 수 있습니다. 따라서 미들웨어 체인 내에서 여러 가지 작업을 수행할 수 있으며, 각 미들웨어는 전달된 액션을 변경하거나 무시할 수도 있다.
위에 미들웨어 개념으로 next 함수를 사용해서 Redux 미들웨어의 예시로, Redux 스토어에 적용되는 로깅 미들웨어를 구현하면 아래와 같다.
//리덕스 미들웨어
const loggerMiddleWare = (store) => (next) => (action) => {
//액션 타입으로 log를 그룹화함
console.group(action && action.type);
console.log("이전 상태", store.getState());
console.log("액션", action);
next(action); //다음 미들웨어 혹은 리듀서에게 전달
console.log("다음 상태", store.getState()); //업데이트 된 상태
console.groupEnd();//그룹 끝
};
export default loggerMiddleWare;
3. applyMiddleware
Redux 스토어를 생성할 때 applyMiddleware 함수에 미들웨어를 전달
하면, 해당 미들웨어가 액션이 디스패치되는 과정에서 동작하게 됩니다. 이를 통해 미들웨어는 액션의 전달 및 처리 과정을 가로채어 필요한 작업을 수행할 수 있습니다. 대표적으로 비동기 작업 처리, 로깅, 에러 처리 등이 미들웨어를 통해 수행된다.
Redux의 applyMiddleware를 사용하면 미들웨어를 스토어에 쉽게 적용할 수 있으며, 애플리케이션의 기능을 확장하고 향상시킬 수 있다.
//리덕스 미들웨어를 스토어에 적용
const store = createStore(rootReducer, applyMiddleware(loggerMiddleWare));
index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { legacy_createStore as createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import "./index.css";
import App from "./App";
import rootReducer from "./modules";
import loggerMiddleWare from "./lib/loggerMiddleware";
//리덕스 미들웨어를 스토어에 적용
const store = createStore(rootReducer, applyMiddleware(loggerMiddleWare));
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
실행 결과
counter/INCREASE
이전 상태 {counter: 0}
액션 {type: 'counter/INCREASE', payload: SyntheticBaseEvent}
다음 상태 {counter: 1}
counter/DECREASE
이전 상태 {counter: 1}
액션 {type: 'counter/DECREASE', payload: SyntheticBaseEvent}
다음 상태 {counter: 0}