미들웨어의 기본 구조
const myMiddleware = store => next => action => {
const result = next(action) // action 전달
return result // dispatch(action) 과 같다
}
// index.js
const store = createStore(rootReducer, **applyMiddleware**(myMiddleware))
- 액션이 최종적으로 reducer에게 전달되기 전에, 부가적인 작업을 수행하기 위해 만들어진 함수
- 미들웨어에서 부가적인 작업을 마쳤다면, 다음 미들웨어에게 액션을 전달하기 위해 next(action) 함수를 호출한다. 만약 next(action) 함수를 호출하지 않으면 action이 reducer에게 전달되지 않는다.
- 다음 미들웨어가 없는데 next(action) 함수를 호출하면 그 action은 reducer에게 전달된다.
- applyMiddleware 함수를 통해서 스토어에 미들웨어를 등록할 수 있다.
redux-thunk
npm i redux-thunk
import ReduxThunk from 'redux-thunk'
// index.js
const store = createStore(reducer, coomposeWithDevTools(applyMiddleware(ReduxThunk)))
// thunk 함수
export function thunk() {
return async (dispatch, getState [,withExtraArgument]) => { // 액션 함수 반환
try {
const res = await axios.get('https:// ~~~') // 비동기 처리
dispatch({type: '..', payload: res}) // reducer 에게 액션 전달
} catch (error) {
// 에러 처리
}
}
}
// container 컴포넌트
dispatch(thunk())
- Thunk 미들웨어는 액션 생성자이다.
- Thunk 미들웨어가 생성하는 액션은 함수로 되어 있다.
- Thunk 미들웨어의 액션 함수는 store의 dispatch, getState를 인자로 전달받는다.
- 추가적으로 withExtraArgument 에 history 객체를 전달하면 thunk 내부에서 라우팅 작업을 할 수 있게 된다.
- Thunk 미들웨어의 액션 함수 내부에서 비동기 처리를 할 수 있다.
redux-promise
npm i redux-promise
import promiseMiddleware from 'redux-promise'
// index.js
const store = createStore(rootReducer, applyMiddleware(promiseMiddleware))
// 액션 생성자
export const async getInfo() {
const res = await axios.get('~~') // 비동기 처리. data는 promise 객체
return { type: '..', payload: res.data } // 액션 반환
}
- Thunk 미들웨어는 액션이 함수로 되어 있어서 단지 비동기 작업을 수월하게 할 수 있는 것이지만, promise 미들웨어는 비동기 작업에 특화된 미들웨어이다.
- promise 미들웨어를 store에 등록하면, 액션의 payload 속성에 promise 객체를 할당할 수 있게 된다. 그 promise 객체는 axios를 통한 API 통신 객체이다.