본문 바로가기

Redux

[Redux 강의노트] Redux Middleware | redux-saga

반응형

redux-thunk

- 함수를 dispatch해주는 미들웨어

redux-saga

- 액션을 모니터링하고 있다가 특정액션이 발생하면 특정작업을 하는 방식

- 자바스크립트의 Generator 문법에 기반한 미들웨어

 

thunk와의 차이점

1. 비동기 작업 진행시 기존 요청을 취소할 수 있다.

2. 특정 액션이 발생할 때 이에 따라 다른 액션을 디스패치하거나 자바스크립트 코드를 실행할 수 있다.

3. 웹소켓을 사용하는 경우 Channel이라는 기능을 사용하여 더 효율적인 코드를 관리 할 수 있다. 

4. 비동기 작업 실패시  재시도 하는 기능을 구현할 수 있다.

 

Generator 문법

- 함수의 흐름을 특정구간에 멈춰놓았다가 다시 실행 할 수 있다.

- 결과값을 여러번 내보낼 수 있다.

 

function* generatorFunction(){
    console.log("안녕하세요");
    yield 1; //함수의 흐름을 멈춰놨다가 1 이라는 값을 반환
    console.log("제너레이터 함수");
    yield 2;       
    console.log("function*");
    yield 3;
    return 4;
}

const generator = generatorFunction()
//undefined

generator
//generatorFunction {<suspended>} //멈춰있는 상태

generator.next()
//안녕하세요
//{value: 1, done: false}

generator
//generatorFunction {<suspended>}

generator.next()
//instrument.js:110 제너레이터 함수
//{value: 2, done: false}

generator.next()
//instrument.js:110 function*
//{value: 3, done: false}

generator.next()
//{value: 4, done: true}

generator
//generatorFunction {<closed>}

 

 

redux-saga 사용해보기

 

//redux-saga 미들웨어가 수행하도록 작업을 명령하는 것 : effect
//delay : 기다리는것, put : 특정액션을 dispatch해라
import { delay, put, takeEvery, takeLatest } from "redux-saga/effects";

const INCREASE = "counter/INCREASE";
const DECREASE = "counter/DECREASE";
const INCREASE_ASYNC = "INCREASE_ASYNC";
const DECREASE_ASYNC = "DECREASE_ASYNC";

export const increase = () => ({
  type: INCREASE,
});

export const decrease = () => ({
  type: DECREASE,
});

//redux-saga사용할 것
export const increaseAsync = () => ({ type: INCREASE_ASYNC });
export const decreaseAsync = () => ({ type: DECREASE_ASYNC });

//redux-saga : generator함수로 직성
function* increaseSaga() {
  yield delay(1000);
  yield put(increase());
}

//redux-saga : generator함수로 직성
function* decreaseSaga() {
  yield delay(1000);
  yield put(decrease());
}

export function* counterSaga() {
  //takeEvery : INCREASE_ASYNC액션 dispatch될때마다 increaseSaga를 실행함
  yield takeEvery(INCREASE_ASYNC, increaseSaga);
  //takeLatest : 가장 마지막에 들어온 DECREASE_ASYNC만 처리됨
  yield takeLatest(DECREASE_ASYNC, decreaseSaga);
}

const initialState = 0;

export default function counter(state = initialState, action) {
  switch (action.type) {
    case INCREASE:
      return state + 1;
    case DECREASE:
      return state - 1;
    default:
      return state;
  }
}
export function* rootSaga() {
  yield all([counterSaga()]);
}
const customHistory = createBrowserHistory();
const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  rootReducer,
  composeWithDevTools(
    applyMiddleware(
      sagaMiddleware,
      ReduxThunk.withExtraArgument({ history: customHistory }),
      logger
    )
  ) //logger을 사용할때 맨 마지막에 있어야함
);

//rootsaga등록
sagaMiddleware.run(rootSaga);

'Redux' 카테고리의 다른 글

Redux Toolkit  (0) 2021.05.05
[Redux 강의노트] Redux Middleware | logger, thunk  (0) 2021.01.09
[Redux강의노트] Redux  (0) 2021.01.03
React → Redux | Redux 101 (2/2)  (0) 2020.11.24
VanillaJS → Redux | Redux 101 (1/2)  (0) 2020.11.18