티스토리 뷰
1. Redux Middleware
1.0 개념
기존 | Middleware 사용 |
Action -> Dispatcher -> Reducer 실행 | Action -> Dispatcher -> Middleware 전처리 -> Reducer 실행 -> Middleware 후처리 |
:: 한번에 처리 | :: Reducer 실행에는 Only 상태 변경에 대한 역할 및 책임 :: 다른 side-Effect는 Middleware에서 처리 |
- proxy 패턴과 유사
1) 전처리 :: Action -> Dispatch 후 Middleware가 이후 활동을 가로채고 작업 후 다시 Dispatcher로 반환
2) 후처리 :: Action을 받은 Reducer의 store처리 후, Middleware가 활동에 관여하여 작업 처리
1.1 제공 파라미터
// 미들웨어 기본 템플릿
const middleware = store => next => action => {
// 처리 로직
};
// 일반 함수 형식
const middleware = function(store) {
return function(next) {
return function(action) {
// 처리 로직
}
}
}
매개 변수 | 설명 |
1. Store | :: Redux store 객체 :: 상태 조회(dispatch, getState) + subscribe 등의 메서드를 포함. |
2. Next | :: 현재 미들웨어 체인에서 다음 미들웨어를 호출하는 함수 :: dispatcher(action)이듯 next(action) |
3. Action | :: 디스패치된 액션 객체 :: type과 관련된 데이터를 포함. |
1.2 EX - logger
export const dispatchWithLog = (store) => (next) => (action) => {
console.log("- 이전 State : ", store.getState());
console.log("- Action : ", action);
next(action);
console.log("- 이후 State : ", store.getState());
};
export const store = configureStore({
reducer: {
theme: themeSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(dispatchWithLog),
});
위의 내용에서 "고차함수", "커링", "클로저"가 나옴
- 고차 함수 :: 다른 함수를 인자로 받거나 함수를 결과로 반환하는 함수
// 고차함수: 함수를 인자로 받는 함수
function greeting(name, callback) {
return `Hello, ${callback(name)}!`;
}
// 콜백 함수
function uppercaseName(name) {
return name.toUpperCase();
}
console.log(greeting('Alice', uppercaseName)); // "Hello, ALICE!"
2. 클로저
:: 함수가 자기 자신을 포함한 외부 함수의 변수에 접근할 수 있는 특성
:: 함수와 그 함수의 선언 시의 스코프를 기억하는 함수
function outer() {
let count = 0; // outer 함수의 지역 변수
return function inner() {
count++; // count는 inner 함수에서 접근할 수 있음
return count;
}
}
const counter = outer(); // counter는 inner 함수가 반환된 함수
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
3. 커링
:: 여러 인자를 받는 함수를 하나의 인자만 받는 함수들로 변환하는 기법
:: 함수 호출 시에 연속적인 인자 전달
// 커링된 함수
function multiply(a) {
return function(b) {
return a * b;
}
}
const multiplyBy2 = multiply(2);
console.log(multiplyBy2(5)); // 10
const multiplyBy3 = multiply(3);
console.log(multiplyBy3(5)); // 15
2. Redux Middleware 구현체
간단하기 흝어보기
React.js - redux middleware(리덕스 미들웨어, redux-thunk, redux-saga)
소프트웨어 공학에서 미들웨어란 운영체제와 응용 소프트웨어 중간에서 조정과 중개의 역할을 수행하는 소프트웨어를 말한다.리덕스 미들웨어는 액션을 디스패치 했을 때 리듀서에서 이를 처
velog.io
미들웨어 | 주요 기능 | 특징 |
1. Redux-logger | 액션과 상태 변화를 콘솔에 출력 | - 디버깅과 로그 출력에 유용 - 액션 디스패치 시 prev state, action, next state 출력 / 로깅 |
2. Redux-thunk | 비동기 액션 처리 (Promise 기반) | - 액션 생성자가 함수형으로 작성됨 - promise 기반 - 함수형 액션을 사용하여 비동기 작업 처리 (dispatch 활용) |
3. Redux-saga | 복잡한 비동기 로직 처리 | - 제너레이터(Generator) 함수 사용 - 비동기 로직을 순차적으로 처리, 새로운 액션을 생성하고 전달 - hunk와의 차이 :: ation의 복잡한 체인을 처리 - 여러 비동기 작업들에 대한 순차적 처리 |
1. Redux-logger
- 설치
npm install redux-logger
- 예시
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
// 리듀서 예시
const rootReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};
const store = createStore(rootReducer, applyMiddleware(logger));
// 액션 디스패치
store.dispatch({ type: 'INCREMENT' });
2.2 Redux-thunk
- 설치
npm install redux-thunk
- 예시
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
// 리듀서 예시
const rootReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};
// 비동기 액션 생성자
const incrementAsync = () => {
return (dispatch) => {
setTimeout(() => {
dispatch({ type: 'INCREMENT' });
}, 1000);
};
};
const store = createStore(rootReducer, applyMiddleware(thunk));
// 비동기 액션 디스패치
store.dispatch(incrementAsync());
2.3 Redux-saga
- 설치
npm install redux-saga
- 예시
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { takeEvery, put } from 'redux-saga/effects';
// 리듀서 예시
const rootReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};
// 제너레이터 함수 (saga)
function* incrementAsync() {
yield new Promise(resolve => setTimeout(resolve, 1000));
yield put({ type: 'INCREMENT' });
}
// 루트 saga
function* rootSaga() {
yield takeEvery('INCREMENT_ASYNC', incrementAsync);
}
// 미들웨어 설정
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
// saga 실행
sagaMiddleware.run(rootSaga);
// 액션 디스패치
store.dispatch({ type: 'INCREMENT_ASYNC' });
2.1 Redux Thunk 상세
:: 보통 redux의 Action은 객체 But, Thunk의 경우,
:: Dispatch에 넘기는 Action이 객체가 아닌 promise 기반의 비동기 함수를 넘김
:: getState를 사용해 store에서의 현재 상태를 가져올 수 있음
const incrementIfOdd = () => {
return (dispatch, getState) => {
const currentCount = getState().count;
if (currentCount % 2 === 0) {
dispatch({ type: 'INCREMENT' });
}
};
};
store.dispatch(incrementIfOdd()); // currentCount가 홀수일 때만 INCREMENT 액션 디스패치
2.2 비동기 데이터 fetching
:: RTK Query, React Query 및 SWR
:: Redux-Thunk + Redux-Saga 를 조합하여 비동기 API + 전역 상태관리 제공
- Redux-Thunk와 Redux-Saga의 비동기 API + Side Effect 지원 부분 => Custom Hook 제공
1) SWR :: 자동 중복 제거, 캐시, 공유
2) RTK Query
:: 위 SWR 기능
+ Saga 내 try-catch → 성공여부 판단 가능한 Hook 값을 활용
+ 자동 캐싱 및 Re-Fetching :: 유한 키값 설정으로 데이터 페칭 요청을 구분
3) React Query :: 위 RTK Query 기능과 거의 유사
예시 코드
Redux Thunk and RTK qurey | Notion
Redux Thunk를 사용한 비동기 호출
creative-soup-a08.notion.site
참고
ASAC 수업자료
처음 만난 리덕스 (Redux): redux-saga - FrontOverflow
상태관리의 기초 개념과 함께 리덕스의 기초를 탄탄하게 다질 수 있습니다.
www.frontoverflow.com
'정리용 > react' 카테고리의 다른 글
[React] useForm 사용 - 시작 단계 (0) | 2025.02.28 |
---|---|
[React] React Hook Form 정리 (0) | 2025.02.28 |
[React - 상태 관리] Flux Architecture와 Redux (0) | 2025.02.25 |
[07-React] 6-8. React Hook :: useCallback (0) | 2025.01.17 |
[07-React] 6-6. React Hook :: useLayoutEffect (0) | 2025.01.17 |
- Total
- Today
- Yesterday
- ASAC
- react
- ssh
- Nginx
- useState
- useLayoutEffect
- useEffect
- useCallback
- asac7기
- memo
- useContext
- asac7#asac
- useMemo
- useReducer
- acac
- asac#asac7기
- asac7
- acas#acas7기
- git
- useRef
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |