반응형
API 서버를 연동할때, 리덕스를 사용하고 있으며 이러한 비동기 작업을 관리해야한다면 미들웨어를 사용하여 매우 효율적이고 편하게 상태관리를 할 수 있다.
작업환경준비
프로젝트 만들기
$ mkdir react-middleware
$ cd react-middleware
$ npm init vite
$ npm install
$ npm install react-redux redux-actions
counter 리덕스 모듈
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);
const initialState = 0;
const counter = handleActions(
{
[INCREASE]: state => state + 1,
[DECREASE]: state => state - 1
},
initialState
);
export default counter;
루트리듀서 생성
modules/index.js
import { combineReducers } from 'redux';
import counter from './counter';
const rootReducer = combineReducers({
counter
});
export default rootReducer;
스토어생성
main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import rootReducer from './modules/index.js'
import { applyMiddleware, legacy_createStore as createStore } from "redux";
import { Provider } from 'react-redux';
import loggerMiddleware from './lib/loggerMiddleware.js';
const store = createStore(rootReducer, applyMiddleware(loggerMiddleware));
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
)
카운터 컴포넌트와 컨테이너
components/Counter.jsx
import React from 'react'
const Counter = ({ onIncrease, onDecrease, number }) => {
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
)
}
export default Counter
containers/CounterContainer.jsx
import React from 'react'
import Counter from '../components/Counter'
import { connect } from 'react-redux'
import { increase, decrease } from '../modules/counter'
const CounterContainer = ({ number, increase, decrease }) => {
console.log("test")
return (
<Counter number={number} onIncrease={increase} onDecrease={decrease} />
)
}
export default connect(
state => ({
number: state.counter
}),
{
increase,
decrease,
}
)(CounterContainer);
App.jsx에서 CounterContainer를 렌더링하여 확인한다.
미들웨어란?
리덕스 미들웨어는 액션을 디스패치 했을때 리듀서에서 이를 처리하기에 앞서 사전에 지정된 작업을 실행한다. 미들웨어는 액션과 리듀서 사이의 중간자라고 볼 수 있다.
미들웨어 만들어보기
직접 만들어서 사용할일은 별로 없지만 미들웨어를 이해하기 위해 간단하게 만들어보겠다.
만들 로깅 미들웨어는
- 액션이 디스패치 될 때마다
- 액션의 정보와
- 액션이 디스패치 되기 전후의 상태를
- 콘솔에 보여준다.
// 미들웨어 기본구조
const loggerMiddleware = store => next => action => {
console.group(action && action.type); // action 타임으로 log를 그룹화
console.log('이전상태: ', store.getState());
console.log('액션', action);
next(action);
console.log('다음상태: ', store.getState());
console.groupEnd();
}
export default loggerMiddleware
main.jsx
에서 미들웨어를 적용한다.
import { applyMiddleware, legacy_createStore as createStore } from "redux";
import loggerMiddleware from './lib/loggerMiddleware.js';
const store = createStore(rootReducer, applyMiddleware(loggerMiddleware));
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
)
미들웨어 특징
- 미들웨어 내부에서 store.dispatch를 사용하면 첫번째 미들웨어부터 다시 처리한다. 만약 미들웨어에서 next를 사용하지 않으면 액션이 리듀서에 전달되지 않는다.
- 여러종류의 작업을 처리할 수 있음
- 특정조건에 따라 액션을 무시하게 할 수 있음
- 특정조건에 따라 액션정보를 가로채서 변경한후, 리듀서에 전달할 수 있음
- 특정액션에 기반하여 새로운 액션을 여러번 디스패치 할 수있음
이러한 미들웨어 속성을 사용하여 네트워크 요청과 같은 비동기 작업을 관리하면 매우 유용하다.
redux-logger
오픈소스 커뮤니티에 올라와있는 리덕스로거라는 라이브러리이다.
콘솔에 나타나는 형식도 깔끔하며 더 잘만들어졌다. 콘솔에 색상도 입혀지고, 액션 디스패치 시간도 나타난다.
$ npm install redux-logger
main.jsx
import { applyMiddleware, legacy_createStore as createStore } from "redux";
import { createLogger } from 'redux-logger';
const logger = createLogger();
const store = createStore(rootReducer, applyMiddleware(logger));
반응형
'Frontend > React' 카테고리의 다른 글
[React] 리액트 미들웨어 redux-saga (1) | 2023.12.28 |
---|---|
[React] 리액트 미들웨어 redux-thunk (0) | 2023.12.28 |
[Redux] 리덕스를 사용하여 상태 관리 (0) | 2023.12.28 |
[React] Context API (0) | 2023.12.28 |
[React] immer를 사용해 쉽게 불변성 유지! (0) | 2023.12.28 |