Redux Middleware ํบ์๋ณด๊ธฐ! ๐ฆธโ๏ธ๐ฆธโ๏ธ
Redux๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด, ๋จ์ํ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฑธ ๋์ด ๋ ๋ณต์กํ ์์ ์ ์ฒ๋ฆฌํด์ผ ํ ๋๊ฐ ์์ด์. ์๋ฅผ ๋ค์ด, ๋น๋๊ธฐ API ํธ์ถ์ด๋ ๋ก๊ทธ ์ถ๋ ฅ ๊ฐ์ ์ผ์ ๋ง์ด์ฃ . ๋ฐ๋ก ์ฌ๊ธฐ์ Redux Middleware๊ฐ ๋ฑ์ฅํฉ๋๋ค.
Middleware๋ ๋ง์น ์ก์ ๊ณผ ๋ฆฌ๋์ ์ฌ์ด์์ ์ผ์ ์ฒ๋ฆฌํ๋ ๋น๋ฐ ์์ ๊ฐ์์. ์ค๋์ ์ด ์์์ ์ ๋๋ก ์ดํดํ๊ณ , ์ค๋ฌด์์๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ํํ ์๋ ค๋๋ฆด๊ฒ์. ๐
๐ Middleware๋ ๋ฌด์์ผ๊น?
Redux์์ Middleware๋ ์ก์ ์ด ๋ฆฌ๋์์ ๋๋ฌํ๊ธฐ ์ ์ ์ค๊ฐ์์ ๊ฐ๋ก์ฑ๊ณ ์ถ๊ฐ ์์ ์ ์ํํ๋ ๋๊ตฌ์ ๋๋ค.
์ฝ๊ฒ ๋งํด:
- ์ก์ ์ด ๋์คํจ์น(dispatch)๋๋ฉด,
- Middleware๊ฐ ๊ทธ ์ก์ ์ ๊ฐ๋ก์ฑ,
- ๋ญ๊ฐ ์์ ์ ํ ๋ค์ ๋ฆฌ๋์๋ก ๋๊ธฐ๊ฑฐ๋, ๋๊ธฐ์ง ์๊ฑฐ๋(!) ํ ์ ์์ฃ .
โจ ๋น์ : Middleware๋ ํ๋ฐฐ๋ฅผ ์ค๊ฐ์ ๊ฐ๋ก์ฑ์ ๋ฌผ๊ฑด์ ํ์ธํ๊ณ , ํฌ์ฅ์ง๋ฅผ ๋ฐ๊ฟ ๋ค์ ๋ฐฐ๋ฌํ๋ ํ๋ฐฐ ์ฌ์ฌ๊ด์ด์์. ๐ฆ
๐ฆ Middleware์ ์ฃผ์ ์ญํ
Middleware๊ฐ ์์ผ๋ฉด Redux๋ ์ ๋ง ๋จ์ํ ์ํ ๊ด๋ฆฌ ๋๊ตฌ์ผ ๋ฟ์ด์์. Middleware ๋๋ถ์ Redux๋ ๋ค์ํ ์ผ์ ํ ์ ์์ฃ
1๏ธโฃ ๋น๋๊ธฐ ์์ ์ฒ๋ฆฌ
API ์์ฒญ์ด๋ ํ์ด๋จธ ๊ฐ์ ์์ ์ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ ์ ์์ด์.
2๏ธโฃ ๋ก๊น
๋๋ฒ๊น ์ ์ํด ์ก์ ๊ณผ ์ํ๋ฅผ ๋ก๊น ํ ์ ์์ด์.
3๏ธโฃ ์กฐ๊ฑด๋ถ ์ก์ ์ฒ๋ฆฌ
ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ์ก์ ์ ๋ง๊ฑฐ๋, ์๋ก์ด ์ก์ ์ ์ถ๊ฐ๋ก ๋์คํจ์นํ ์ ์์ด์.
4๏ธโฃ ์ถ๊ฐ์ ์ธ ์ก์ ์์ฑ
ํ๋์ ์ก์ ์ ์ฌ๋ฌ ๊ฐ์ ์ก์ ์ผ๋ก ๋ณํํ๊ฑฐ๋, ์๋์ผ๋ก ์๋ก์ด ์ก์ ์ ๋์คํจ์นํ ์ ์์ด์.
โ๏ธ Middleware์ ๋์ ์๋ฆฌ
Redux Middleware๋ store์ dispatch ๋ฉ์๋๋ฅผ ํ์ฅํด์ ๋์ํฉ๋๋ค.
Middleware๋ ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ ๋ฐ๋ฆ ๋๋ค:
- store: ๋ฆฌ๋์ค ์คํ ์ด๊ฐ ์์ฑ๋ฉ๋๋ค.
- dispatch(action): ์ก์ ์ด ๋์คํจ์น๋ฉ๋๋ค.
- Middleware: ์ก์ ์ ๊ฐ๋ก์ฑ ์ถ๊ฐ ์์ ์ ์ํํฉ๋๋ค.
- reducer: ๊ฐ๊ณต๋ ์ก์ ์ด ๋ฆฌ๋์๋ก ์ ๋ฌ๋ฉ๋๋ค.
- store: ๋ฆฌ๋์๊ฐ ์๋ก์ด ์ํ๋ฅผ ๋ฐํํฉ๋๋ค.
๐ฉ๐ป๐ป Middleware ์ฌ์ฉํด๋ณด๊ธฐ
๊ธฐ๋ณธ ๋ก๊ฑฐ(Logger) Middleware ๊ตฌํ
๊ฐ์ฅ ๊ฐ๋จํ ์๋ก, ์ก์ ๊ณผ ์ํ๋ฅผ ๋ก๊ทธ๋ก ์ถ๋ ฅํ๋ Middleware๋ฅผ ๋ง๋ค์ด๋ณผ๊ฒ์.
const loggerMiddleware = (store) => (next) => (action) => {
console.log('๋์คํจ์น๋ ์ก์
:', action);
const result = next(action); // ๋ค์ Middleware ๋๋ ๋ฆฌ๋์๋ก ์ ๋ฌ
console.log('์
๋ฐ์ดํธ๋ ์ํ:', store.getState());
return result;
};
๐ ์ฌ๊ธฐ์:
- store: Redux ์คํ ์ด
- next: ๋ค์ Middleware ๋๋ ๋ฆฌ๋์
- action: ํ์ฌ ์ฒ๋ฆฌ ์ค์ธ ์ก์
์ด Middleware๋ ์ก์ ์ ๋ก๊ทธ๋ก ์ถ๋ ฅํ๊ณ , ๋ฆฌ๋์๋ก ๋๊ธด ๋ค ์ ๋ฐ์ดํธ๋ ์ํ๋ ์ถ๋ ฅํด์.
๐ Redux์์ Middleware ์ ์ฉํ๊ธฐ
Redux์์ Middleware๋ฅผ ์ ์ฉํ๋ ค๋ฉด applyMiddleware๋ฅผ ์ฌ์ฉํด์ผ ํด์.
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers';
import loggerMiddleware from './middlewares/logger';
const store = createStore(
rootReducer,
applyMiddleware(loggerMiddleware) // ์ฌ๊ธฐ์ Middleware ๋ฑ๋ก!
);
๐ผ ์ค๋ฌด์์ ํํ ์ฐ๋ Middleware๋ค
1๏ธโฃ Redux Thunk
Redux Thunk๋ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ Middleware์์.
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
const fetchData = () => async (dispatch) => {
dispatch({ type: 'FETCH_DATA_START' });
const data = await fetch('/api/data').then((res) => res.json());
dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });
};
store.dispatch(fetchData());
Thunk๋ ์ก์ ๋์ ํจ์๋ฅผ ๋์คํจ์นํ ์ ์๋๋ก ํด์ค๋๋ค. ๋น๋๊ธฐ API ํธ์ถ ์ ์ ์ฉํ์ฃ .
2๏ธโฃ Redux Saga
Redux Saga๋ Thunk๋ณด๋ค ๋ ๊ฐ๋ ฅํ๊ณ ๋ณต์กํ ๋น๋๊ธฐ ์์ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋๊ตฌ์์. yield์ generator๋ฅผ ํ์ฉํด์ ์ด๋ฒคํธ๋ฅผ ์ ์ธ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ต๋๋ค.
import { call, put, takeEvery } from 'redux-saga/effects';
function* fetchData() {
const data = yield call(fetch, '/api/data');
yield put({ type: 'FETCH_DATA_SUCCESS', payload: data });
}
function* rootSaga() {
yield takeEvery('FETCH_DATA_REQUEST', fetchData);
}
3๏ธโฃ Redux Logger
Redux Logger๋ ๋ก๊น ์ ํนํ๋ Middleware๋ก, ๋๋ฒ๊น ์ ํฐ ๋์์ ์ค์.
import logger from 'redux-logger';
const store = createStore(rootReducer, applyMiddleware(logger));
๐ Middleware ๋ง๋ค๊ธฐ ์ค์ต
์ก์ ์ฐจ๋จ๊ธฐ: ํน์ ์ก์ ์ ๋ง์๋ณด์!
const blockActionMiddleware = (store) => (next) => (action) => {
if (action.type === 'BLOCK_THIS_ACTION') {
console.warn('์ด ์ก์
์ ์ฐจ๋จ๋์์ต๋๋ค:', action);
return; // ๋ฆฌ๋์๋ก ์ ๋ฌํ์ง ์์!
}
return next(action); // ๋ค๋ฅธ ์ก์
์ ์ ์ ์ฒ๋ฆฌ
};
๋ค์ค ์ก์ ์ฒ๋ฆฌ๊ธฐ: ํ ์ก์ ์ผ๋ก ์ฌ๋ฌ ์์ ์คํํ๊ธฐ
const multiActionMiddleware = (store) => (next) => (action) => {
if (Array.isArray(action)) {
action.forEach((singleAction) => store.dispatch(singleAction));
return;
}
return next(action);
};
๐ซ๏ธ Middleware์ ์ฅ์ ๊ณผ ํ๊ณ
์ฅ์
- ์ ์ฐ์ฑ: ๋ค์ํ ์์ ์ ์ฒ๋ฆฌ ๊ฐ๋ฅ (๋ก๊น , ๋น๋๊ธฐ, ์กฐ๊ฑด๋ถ ์ก์ ๋ฑ)
- ํ์ฅ์ฑ: ๊ธฐ์กด Redux ํ๋ฆ์ ์ํฅ์ ์ฃผ์ง ์์ผ๋ฉด์ ๊ธฐ๋ฅ ์ถ๊ฐ ๊ฐ๋ฅ
- ์ฝ๋ ๋ถ๋ฆฌ: ์ก์ ๊ณผ ๋ฆฌ๋์์ ์ฑ ์์ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์
ํ๊ณ
- ๋ณต์ก์ฑ ์ฆ๊ฐ: ๋๋ฌด ๋ง์ Middleware๋ ์ ์ง๋ณด์๋ฅผ ์ด๋ ต๊ฒ ํ ์ ์์
- ๋๋ฒ๊น ๋์ด๋: Middleware์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ ์ถ์ ํ๊ธฐ ์ด๋ ค์ธ ์ ์์
๐ค๏ธ Redux Middleware์ ๋ฏธ๋
Middleware๋ Redux ์ํ๊ณ์์ ํ์์ ์ธ ๋๊ตฌ์ด์ง๋ง, ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ์ ์ ํ ์ ํํ๊ณ ์กฐํฉํ๋ ๊ฒ์ด ์ค์ํด์. Thunk์ Logger ๊ฐ์ ๊ฐ๋จํ ๋๊ตฌ๋ถํฐ Saga ๊ฐ์ ๋ณต์กํ ๋๊ตฌ๊น์ง, ์ฌ๋ฌ๋ถ์ ํ๋ก์ ํธ์ ํ ์คํ์ผ์ ๋ง๋ ์ ํ์ ํ์ธ์!
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น!๐ท