티스토리 뷰
React -redux thunk, redux saga
>reudx-saga에 들어가기에 앞서,
|redux-thunk란?
redux-saga를 적용시키기 전에 redux-thunk를 먼저 사용해봤다면, 왜 redux-saga를 써야하는지 더 쉽게 파악할 수 있으므로, 시간이 있다면 간단히라도 학습하길 바란다. 아래에서 간단히 소개하겠다.
:가장 간단히 설명하자면, 이 미들웨어는 객체 대신 함수를 생성하는 액션 생성함수를 작성 할 수 있게 해준다. 리덕스에서는 기본적으로는 액션 객체를 디스패치한다.
function increment() {
return {
type: INCREMENT_COUNTER
};
}
예전에는 액션생성함수에서 위와 같은 type을 가지는 객체를 생성해 줬었다면
function increment() {
return {
type: INCREMENT_COUNTER
};
}
function incrementAsync() {
return dispatch => { // dispatch 를 파라미터로 가지는 함수를 리턴합니다.
setTimeout(() => {
// 1 초뒤 dispatch 합니다
dispatch(increment());
}, 1000);
};
}
dispatch, getState
를 파라미터로 받게 한다면 아래와 같이 스토어의 상태에도 접근 할 수있다. 따라서, 현재의 스토어 상태의 값에 따라 액션이 dispatch 될 지 무시될지 정해줄 수 있다.function incrementIfOdd() {
return (dispatch, getState) => {
const { counter } = getState();
if (counter % 2 === 0) {
return;
}
dispatch(increment());
};
}
redux-thunk
를 통해 만든 액션생성자는 그 내부에서 여러가지 작업을 할 수 있습니다. 이 곳에서 네트워크 요청을 해도 무방하죠. 또한, 이 안에서 액션을 여러번 디스패치 할 수도 있습니다.> redux-saga를 쓰는 이유
요약해서 말하면 비동기처리를 위해서이다.
리덕스 만으로는, 특정 action을 dispatch 받는걸 기다렸다가 dispatch 받았을때, 다른 action을 dispatch하는 동기적인 액션의 dispatch 상황에 대한 것이나 (쉽게 말하면 순서대로 액션을 처리), 디스패치된 액션들을 모두 모아서 병렬적으로 task를 수행한다던지, 외부라이브러리를 사용하고 호출하는것이 어려운데 리덕스 saga를 사용하면 이러한 점들이 해결된다.
그리고 리덕스 사가는 middleware 인데,
"미들웨어는, 액션이 디스패치(dispatch) 되어서 리듀서에서 이를 처리하기전에 사전에 지정된 작업들을 설정합니다. 미들웨어를 액션과 리듀서 사이의 중간자라고 이해하시면 되겠습니다."
라고 velopert님이 간결하게 표현해 주셨다. 이를 리덕스 saga와 연결시켜 보면, 액션을 비동기적으로 디스패치 했을때 미들웨어인 리덕스 사가가 디스패치 액션들을 잡아서, 우리가 입맛에 맞게 리덕스 사가를 이용해 어떤 행동을 취할지 정해주면 이를 바탕으로 reducer에 전달하게 되는것이다.
> redux-saga의 effect
위에서 입맛에 맞게 리덕스 사가를 이용해 준다 하였는데, 이때 사용되는 개념이 redux-saga의 effect이다.
redux-saga는 "Task"라는 개념을 Redux로 가져오기위한 지원 라이브러리입니다. 여기서 말하는 Task란 일의 절차와 같은 독립적인 실행 단위로써, 각각 평행적으로 작동합니다. redux-saga는 이 Task의 실행환경을 제공합니다. 더불어 비동기처리를 Task로써 기술하기 위한 준비물인 "Effect"와 비동기처리를 동기적으로 표현하는 방법을 제공하고 있습니다. Effect란 Task를 기술하기 위한 커맨드(명령, Primitive)와 같은 것으로, 예를들면 다음과 같은 것들이 있습니다.
참고
참고한 글에서 위와 같이 redux-saga에 대해 자세히 말해주고있다. 나도 처음 리덕스 사가를 접했을때, 정말 막막했으니 이해가 안가는게 당연하다. 일단 느낌만 알고 가자. 이 상태에서 위에서 말한 effect들의 종류에 대해서 살펴보자.아래 첨부한 이미지를 참고하면 많은 도움이 된다.
select
: State로부터 필요한 데이터를 꺼낸다.put
: Action을 dispatch한다.take
: Action을 기다린다. 이벤트의 발생을 기다린다.call
: Promise의 완료를 기다린다.fork
: 다른 Task를 시작한다.join
: 다른 Task의 종료를 기다린다.
const cart = yield select(selectCart);
localStorage.setItem('cartCache', JSON.stringify(cart));
const state = yield select();
const nextPage = state.reviewData.meta.reviewPage;
console.log(nextPage);
yield put(setPage(nextPage));
yield take([ADD_CART, REMOVE_CART, CLEAR_CART]);
const cart = yield select(selectCart);
localStorage.setItem('cartCache', JSON.stringify(cart));
:call 은 api요청을 할때 많이 쓰는 efect이다. api요청을 해서 promise가 resolve되면 그 데이터를 받아오게 되는것이다.
const addresses = yield call(getAddressInfo, {
query,
});
yield put(loadAddressesSuccess(addresses));
export function* initDeliveryAt() {
while (true) {
yield take(LOAD_AVAILABLE_DATES);
yield fork(initAvailableDatesFlow);
}
}
export function* initAvailableDatesFlow() {
}
빠르게 훑는 generator
- iterable
- 비동기든 동기든 간에
yield
구문으로 순차적 처리가 가능하다.
function* fetchAll() {
yield [
call(fetchResource, 'users'), // task1
call(fetchResource, 'comments'), // task2,
call(delay, 1000)
]
}
function* main() {
yield call(fetchAll)
}
병렬 이펙트 1
export default function* metaRoot() {
yield all([
watchLoadUserSuccess(),
watchSignOut(),
watchSetServiceType(),
watchPopup(),
initPopup(),
]);
}
'Front end > React' 카테고리의 다른 글
React - navbar item 클릭 후 Link to로 링크 이동시, navbar toggle 되게하기 (0) | 2018.05.24 |
---|---|
React - 네이버 맵 api 활용하기 (0) | 2018.05.12 |
React- Google analytics e-commerce 관련 이벤트 달기 (0) | 2018.03.06 |
React - 리덕스 미들웨어 (0) | 2018.03.02 |
Redux- 리덕스 총정리하기 (0) | 2018.03.02 |