리덕스에서 비동기 작업을 처리할 때 미들웨어로 redux-thunk와 redux-saga를 사용한다.
특정 작업을 나중에 처리하기위해 함수로 감싼 것을 뜻한다.
thunk를 알아보기 위해 generator에 대해서 알아보자.
Generator - Javascript 공식 문서
기본 문법에 속해있는 generator은 .next()를 통해 호출될 때마다 함수가 끝날 때까지 중간의 yield 즉 return 의 값이 달라지는 함수이다. switch문과 어떻게보면 비슷하다고 볼 수 있다.
const gen = function* ss(){
console.log(1)
yield;
console.log(2)
yield;
console.log(3)
yield 3;
}
다음과 같은 함수가 있다고 하자.
그러면 다음과 같이 실행해보자.
ss();
첫번째 ss()의 실행 결과로는gen<suspend>
가 나온다. 함수를 호출했든데도 실행이 되지 않는 것이다.
여기서 next()를 발견할 수 있다.
const ab = gen()
이라고 작성해보자.
yield 3 이라고 한 부분에 value 값이 3이 되었고, 한번 더 실행시키자 done:true
로 바뀐 것을 알 수 있다.
const abc = function*(){
while(true){
console.log('무한반복')
yield
}}
generator함수는 바로 사용할 수 없고, 변수에 담아서만 사용할 수 있다.
실제로 redux-thunk의 코드는 간단하다.
github의 redux-thunk
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => (next) => (action) => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
이렇게 간단한 11줄의 코드로 이루어져 있다. 이 코드에 대해 알아보자.
return dispatch return ({ dispatch, getState }) => (next) => (action) => {}
이 부분이 이해가 안될텐데
const a = ()=>()=>()=>{
console.log('aaa')
}
이것과 비슷하다고 보면 된다.
이 모양은
function a(){
return function (){
return function (){
console.log('aaa')
}
}
}
와 같다.
[front>store>configureStore.js]
...
const loggerMiddleware=({dispatch,getState})=>(next)=>(action)=>{
console.log(action)
return next(action)//action값은 Store생성할 때 createStore 함수의 두번째 인잣값인 enhancer값
const configureStore = ()=>{
const middlewares=[loggerMiddleware]
//개발모드와 배포모드를 다르게 하겠다는 것
const enhancer = process.env.NODE_ENV==='production'
?compose(applyMiddleware(...middlewares))
:composeWithDevTools(applyMiddleware(...middlewares))
const Store=createStore(reducer,enhancer)
//createStore(reducder)===createContext(reducer)
//===createContext(상태초기값)
//reducer 안에 초기값을 가지고 있음
return Store
}
...
이와 같이하면 콘솔창에 다음과 같이 {type:"USER_LOGIN"}
이라고 뜬다. 그러므로 action값은 {type:"USER_LOGIN"}임을 알 수 있다. 이러므로 action값이 reducer에서 받았던 action값 전체임을 알 수 있다. (우리가 항상 action값을 객체로 만들었기 때문에 action은 객체이다. )
dispatch도 함수이고 getState도 함수이다.
thunk는 action값이 function일때만 다르게 주고싶을 때 쓴다. 객체값이면 신경쓰지 않고 쓰는 반면, 함수로 주어질 때 다르게 쓰는 것임.