상태관리를 redux-thunk를 통해 fetch를 받고 store에서 metaData를 관리하도록 변경해 보았다.
💡해당 포스팅에서는 ducks 스타일로 코드를 작성하였습니다.
미들웨어는 액션이 디스패치(dispatch)되어서 리듀서에서 이를 처리하기전에 사전에 지정된 작업들을 설정하는 공간입니다.
💡쉽게 미들웨어는 액션과 리듀서 사이의 중간자라고 이해하도록 해보자!
const loggerMiddleware = store => next => action => {
/* 미들웨어 내용 */
}
next는 store.dispatch와 비슷한 역할을 합니다.
💡 차이점
- next(action)을 했을 때에는 바로 리듀서로 넘기거나, 혹은 미들웨어가 더 있다면 다음 미들웨어 처리가 되도록 진행합니다.
- store.dispatch의 경우에는 처음부터 다시 액션이 디스패치 되는 것 이기 때문에 미들웨어를 다시한번 처리하게 됩니다.
그럼 한번 미들웨어를 만들어보자!
미들웨어
const loggerMiddleware = store => next => action => {
// 현재 스토어 상태값 기록
console.log('현재 상태', store.getState());
// 액션 기록
console.log('액션', action);
// 액션을 다음 미들웨어, 혹은 리듀서로 넘김
const result = next(action);
// 액션 처리 후의 스토어 상태 기록
console.log('다음 상태', store.getState());
console.log('\n'); // 기록 구분을 위한 비어있는 줄 프린트
return result; // 여기서 반환하는 값은 store.dispatch(ACTION_TYPE) 했을때의 결과로 설정됩니다
}
export default loggerMiddleware; // 불러와서 사용 할 수 있도록 내보내줍니다.
미들웨어는 store를 생성할 때 설정합니다.
redux 모듈안에 들어있는 applyMiddleware를 사용하여 설정합니다.
import { createStore, applyMiddleware } from 'redux';
import modules from './modules';
import loggerMiddleware from './lib/loggerMiddleware';
// 미들웨어가 여러개인경우에는 파라미터로 여러개를 전달해주면 됩니다. 예: applyMiddleware(a,b,c)
// 미들웨어의 순서는 여기서 전달한 파라미터의 순서대로 지정됩니다.
const store = createStore(modules, applyMiddleware(loggerMiddleware))
export default store;
리덕스를 사용하는 어플리케이션에서 비동기 작업을 처리할때 쓰는 미들웨어!
객체 대신 함수를 생성하는 액션 생성함수를 작성 할 수 있게 해줍니다.
리덕스에서는 기본적으로 액션 객체를 디스패치 합니다.
const actionCreator = (payload) => ({action: 'ACTION', payload});
만약 특정 액션이 몇 초 뒤에 실행되게 하거나, 현재 상태에 따라 아예 액션이 무시되게 하려면, 일반 액션 생성자로는 할수 없습니다. but, redux-thunk는 이를 가능케합니다!
#case 1
const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
// action 함수
function increment() {
return {
type: INCREMENT_COUNTER
};
}
// thunk 함수
function incrementAsync() {
return dispatch => { // dispatch 를 파라미터로 가지는 함수를 리턴합니다.
setTimeout(() => {
// 1 초뒤 dispatch 합니다
dispatch(increment());
}, 1000);
};
}
이렇게 thunk함수를 작성한다면 나중에 store.dispatch(incrementAsync());를 하면 INCREMENT_COUNTER액션이 1초뒤에 디스패치됩니다!
#case 2
// thunk 함수
function incrementIfOdd() {
return (dispatch, getState) => {
const { counter } = getState();
if (counter % 2 === 0) {
return;
}
dispatch(increment());
};
}
🚨 만약, 리턴하는 함수에서 dispatch, getState를 파라미터로 받게 한다면 스토어의 상태에도 접근이 가능합니다.
따라서, 현재 스토어의 상태 값에 따라 액션이 dispatch될 지, 무시될 지 정해줄 수 있게 됩니다!
redux-thunk 미들웨어에서, 전달받은 액션이 함수형태일 때,
그 함수에 dispatch와 getState를 넣어서 실행해줍니다.
✨오늘의 주인공! Thunk 함수✨
본 프로젝트에는 thunk 외에 saga를 추가로 사용할 예정이다.
따라서 middlewares라는 변수 내부에 사용할 미들웨어들을 묶음으로 지정하여 binding을 했다.