문제 해결

사가를 추가한 후 앱이 멈춘다.

제너레이터 함수의 yield 이펙트를 확인하세요.

아래의 예제를 살펴보도록 합시다:

import { take } from 'redux-saga/effects'

function* logActions() {
  while (true) {
    const action = take() // wrong
    console.log(action)
  }
}

이 예제코드는 애플리케이션을 무한 루프에 빠지게 만듭니다. 왜냐하면 take() 함수는 이펙트에 대한 설명만 생성합니다. 이 코드를 미들웨어를 실행하기 위해 yield 하지 않는 한, while 루프는 일반적인 while 루프와 같이 동작할 것이며, 애플리케이션은 멈추게 될 것이다.

yield 를 추가하는 것은 제너레이터가 일시정지되며, 이펙트를 실행시킬 리덕스 사가 미들웨어에 대한 제어권이 반환된다. take() 함수의 경우, 리덕스 사가 다음 액션의 패턴에 일치할 때까지 기다리며, 일치한 다음에서야 제네레이터를 다시 시작합니다.

위의 예제를 수정하기 위해 take()으로부터 단순히 반환된 이펙트를 yield 합니다.

import { take } from 'redux-saga/effects'

function* logActions() {
  while (true) {
    const action = yield take() // correct
    console.log(action)
  }
}

사가 내에서 디스패치된 액션이 누락됩니다.

사가가 어떤 이펙트에 의해 봉쇄되지 않았는지 확인하세요. 사가가 이펙트가 해결되기를 기다리는 동안은 액션을 디스패치할 수 없습니다.

예를 들어, 다음의 예제를 살펴보도록 하겠습니다.

function* watchRequestActions() {
  while (true) {
    const {url, params} = yield take('REQUEST')
    yield call(handleRequestAction, url, params) // The Saga will block here
  }
}

function* handleRequestAction(url, params) {
  const response = yield call(someRemoteApi, url, params)
  yield put(someAction(response))
}

watchRequestActionsyield call(handleRequestAction, url, params)를 실행시킬 때, 다음의 yield take가 실행되기 전에 handleRequestAction가 종료 될때까지 기다릴 것이다. 예제를 통해 다음의 일련의 이벤트가 발생한다는 것을 추측할수 있다.

UI                     watchRequestActions             handleRequestAction
-----------------------------------------------------------------------------
.......................take('REQUEST').......................................
dispatch(REQUEST)......call(handleRequestAction).......call(someRemoteApi)... Wait server resp.
.............................................................................
.............................................................................
dispatch(REQUEST)............................................................ Action missed!!
.............................................................................
.............................................................................
.......................................................put(someAction).......
.......................take('REQUEST')....................................... saga is resumed

위에서 언급했듯, 봉쇄 호출(blocking call) 에 의해 사가가 봉쇄되면 중간에 디스패치된 액션들은 누락됩니다.

사가의 봉쇄를 피하기 위해, call 대신에 fork를 사용함으로 논 블록킹 호출을 사용할 수 있다.

function* watchRequestActions() {
  while (true) {
    const {url, params} = yield take('REQUEST')
    yield fork(handleRequestAction, url, params) // The Saga will resume immediately
  }
}

results matching ""

    No results matching ""