redux-saga 캡쳐

React는 MVC패턴에서 V(View)를 담당하고 있습니다.

앱이 가벼운 경우에는 State로 데이터를 핸들링 할 수 있지만,

앱이 커질 경우에는 데이터 관리를 별도로 해야하는 요구사항이 생기게됩니다.

이때 사용할 수 있는 것이 Redux와 MobX 등, 상태 관리 라이브러리입니다.

 

redux-saga는 redux의 액션 생성자와 reducer의 순수성을 유지하고 사이드 이펙트를 처리하기 위해 사용합니다.

여기서 사이드 이펙트는 부작용을 발생시키는 어떠한 효과가 아니라,

데이터 요청이나 비동기 작업, 브라우저 캐시 같이 순수하지 않은 작업들을 의미합니다.

 

 

Redux-Saga란?

redux-saga는 리덕스의 미들웨어입니다.

리덕스가 액션을 수행하면 redux-saga에서 디스패치하여 redux의 액션을 가로챈 뒤, 액션의 역할을 수행 하고

다시 액션을 발행하여 데이터를 저장하거나 다른 이벤트를 수행시킵니다.

redux-saga 동작 이미지 출처 uzihoon.com/post/181be130-63a7-11ea-a51b-d348fee141c4

 

redux-saga와 비슷한 라이브러리로 redux-thunk가 있지만,

redux-saga는 redux-thunk에 비해 이펙트 함수를 통해 다양한 작업들을 처리할 수 있습니다.

redux-saga가 좀 더 러닝커브가 높습니다.

  • 비동기 작업 시 기존 요청 취소 처리 가능
  • 특정 액션 발생 시 다른 액션이 디스패치 되도록 할 수 있음
  • 웹 소켓 사용 시 channel 기능을 사용하여 효율적 코드 관리가 가능
  • API 요청이 실패 했을때 재 요청하는 작업을 할 수 있음

이 외에도 다양한 비동기 작업들을 처리 할 수 있습니다.

 

 

자주 사용하는 헬퍼 함수

redux-saga는 스토어에 지정된 액션들이 디스패치되었을 때,

task를 만들기 위해 내부 함수들을 감싸는 헬퍼 이펙트를 제공합니다. 

 

all

제너레이터 함수를 배열의 형태로 인자로 넣어주면 병렬로 동시에 실행됩니다.

이때 모든 함수에 대한 결과가 resolve될 때까지 블럭됩니다. 

 

put

특정 액션의 디스패치하도록 합니다.

결과를 스토어에 디스패치(put) 합니다.

 

call, apply

순수 객체만 리턴하는 함수입니다. 오브젝트 메소드 호출을 지원합니다.

첫번째 파라미터는 함수이며 나머지 파라미터는 해당 함수에 넣을 인수 값 입니다.

액션이 발생하면 전달한 함수를 호출하여 실행합니다.

API가 리턴될때까지 블럭되며, 비동기 함수 호출 시 용이합니다.

call과 apply는 두번째 인자 값의 차이만 있습니다.

 

delay

설정된 시간 이후에 resolve를 하는 Promise 객체를 리턴합니다.

제너레이터를 정지하는데 사용할 수 있습니다.

 

takeEvery

액션이 발생하게되면 task를 실행합니다.

task가 종료되기 전에 또 다른 액션이 발생할 경우, 또 하나의 새로운 task를 실행합니다.

 

takeLatest

액션이 발생하게되면 task를 실행합니다.

만약 실행 중인 task가 있다면 기존 task를 종료하고 새로운 task를 실행합니다.

실수로 여러번 클릭했을때를 방지하거나 마지막에 요청된 데이터를 보여줄 때 사용합니다.

 

takeLeading

액션이 발생하게되면 task를 실행합니다.

해당 task의 실행이 완료되기 전까지 뒤에 오는 이벤트들을 블럭합니다.

이후 task가 완료되면 액션에 대해 수신합니다.

 

throttle

초 이내 요청을 한 번만 보냅니다.

마지막 함수가 호출된 후 일정 시간이 지나기 전 재 호출하지 않습니다.

스크롤 이벤트 사용 시 용이합니다.

 

debounce

초 이내 요청을 한 번만 보냅니다.

처음 함수나 마지막 함수만 호출 후 일정시간이 지나기 전 재 호출하지 않습니다.

 

 

제너레이터함수

ES6에 포함된 제너레이터 함수는 function* 키워드로 작성합니다.

redux-saga는 이 제너레이터 함수를 적극 활용한 사례입니다.

제네레이터는 제네레이터함수의 반환이며 redux-saga가 작성한 함수를 호출하여 반환받는 객체가 제너레이터입니다.

*이터레이터 프로토콜과 이터러블 프로토콜을 준수합니다.

// 코드출처: https://mskims.github.io/redux-saga-in-korean/basics/DeclarativeEffects.html 
import { takeEvery } from "redux-saga/effects"
import Api from "./path/to/api"

function* watchFetchProducts() {
  yield takeEvery("PRODUCTS_REQUESTED", fetchProducts)
}

function* fetchProducts() {
  const products = yield Api.fetch("/products")
  console.log(products)
}

yield를 이용하여 이펙트들을 호출하고 수행된 내용을 다시 돌려 받아 그 액션을 수행합니다.

redux-saga는 제네레이터를 통해 이펙트를 수행하는 역할을 합니다.

 


참고, 출처

+ Recent posts