1. redux-saga
이번에는 redux-saga 를 통해 비동기 작업을 관리하는 방법을 알아보려고 합니다.
이 미들웨어는 redux-thunk 다음으로 많이 사용되는 비동기 작업 미들웨어입니다.
redux-thunk는 함수 형태의 액션을 디스패치하여 미들웨어에서 해당 함수에 스토어의 dispatch와 getState를 파라미터로 넣어서 사용하는 구조를 가지고 있습니다.
그래서 구현한 thunk 함수 내부에서 원하는 API를 요청하고, 다른 액션의 디스패치하거나 핸져 상태를 조회하기도 했습니다.
대부분의 경우에서는 이전 redux-thunk에서 이런 기능들을 충분히 구현할 수 있습니다.
이번에 다루는 redux-saga는 좀 더 까다롭고 복잡한 상황에서 유용하게 쓸 수 있는 미들웨어입니다.
아래왁 같은 상황에서 redux-saga를 사용하는 것이 유용합니다.
- 기존 요청을 취소 처리해야 할 때(불필요한 중복 요청의 방지)
- 특정 액션이 발생했을 때 다른 액션을 발생시키거나, API 요청 등 리덕스와 관계없는 코드를 실행할 떄
- 웹소켓을 사용할 떄
- API 요청 실패로 재 요청해야할 떄
1.1 제너레이터 함수 이해하기
redux-saga에서는 'ES6' 에서 새롭게 추가된 제너레이터(generator) 함수라는 문법을 사용합니다.
보통 일반적인 상황에서는 많이 사용되지 않기 떄문에 처음 이해하는데 진입 장벽이 있습니다.
먼저 제너레이터 함수 문법에 대해 알아 보겠습니다. 이 문법의 핵심 기능은 함수를 작성할 떄 함수를 특정 구간에 멈춰 놓을수도 있고, 원할 떄 다시 돌아가게 하는 것이 가능합니다.
아래와 같은 함수가 있다고 가정해 보겠습니다.
function weirFunction() {
return 1
return 2
return 3
return 4
return 5
}
하나의 함수에서 값을 여러개 반환하는 것을 불가능합니다.
따라서 위의 코드는 작동하지 않을 것 입니다.
호출될때마다 가장 처음에 리턴한 값인 1을 반환하게 됩니다.
그러나 제너레이터 함수를 사용하면 함수에서 값을 순차적으로 반환할 수 있습니다.
또한 함수의 흐름(순서)를 중간에 멈추고 다시 진행시키는 것도 가능합니다.
크롬 개발자 도구 콘솔에서 아래의 함수를 작성해 보세요.
function* generatorFunction() {
console.log('hello')
yield 1
console.log('제너레이터 함수입니다')
yield 2
console.log('function*')
yield 3
return 4
}
제너레이터 함수를 사용하기 위해서는 function* 키워드를 사용합니다.
함수를 작성한 뒤에는 아래의 코드를 추가로 작성하여 제너레이터를 생성하세요.
const generator = generatorFunction()
제너레이터 함수를 호출했을 떄 반환되는 객체를 제너레이터라고 합니다.
이제 다음 코드를 순차적으로 한 줄씩 입력하고 어떤 결과가 나타나는지 콘솔에서 확인해 보세요.
generator.next()
VM1257:2 hello
{value: 1, done: false}
generator.next()
제너레이터 함수입니다
{value: 2, done: false}
generator.next()
function*
{value: 3, done: false}
generator.next()
{value: 4, done: true}
:
제너레이터 함수가 처음 만들어지면 함수의 흐름은 멈춰 있는 상태입니다.
next()가 호출되면 다음 yield가 있는 위치까지 호출하고 다시 함수가 멈추게 됩니다.
제너레이터 함수를 사용하면 함수를 위처럼 중간에 멈출수도 있고 순차적으로 여러 값을 반환시킬 수도 있습니다.
next 함수에 파라미터를 넣으면 제너레이터 함수에서 yield를 사용하여 해당 값을 조회할 수도 있습니다.
이제는 다음 예시 코드를 크롬 개발자 도구 콘솔에서 입력해 보세요.
function* sumGenerator() {
console.log('sumGenerator가 생성되었습니다.')
let a = yield
let b = yield
yield a + b
}
const sum = sumGenerator()
sum.next()
VM2014:2 sumGenerator가 생성되었습니다.
{value: undefined, done: false}
sum.next()
{value: undefined, done: false}
sum.next()
{value: NaN, done: false}done: falsevalue: NaN[[Prototype]]: Object
sum.next()
{value: undefined, done: true}
redux-saga 는 제너레이터 함수 문법을 기반으로 비동기 작업을 관리해주는 미들웨어입니다.
쉽게 설명하면, redux-saga는 디스패치하는 액션을 모니터링해서 그에 따라 필요한 작업을 바로 수행할 수 있도록 해주는 미들웨어입니다.
다음 예시 코드를 크롬 콘솔에서 입력해 보세요.
function* watchGenerator() {
console.log('모니터링 진행중...')
let prevAction = null
while(true) {
const action = yield
console.log('이전 액션:' , prevAction)
prevAction = action
if (action.type === 'hello') {
conosle.log('안녕하세요 Chul Lee입니다')
}
}
}
const watch = watchGenerator()
watch.next()
모니터링 진행중...
{value: undefined, done: false}
watch.next({ type: 'TEST' })
이전 액션: null
{value: undefined, done: false}
watch.next({ type: 'HELLO'})
이전 액션: {type: 'TEST'}
{value: undefined, done: false}
redux-saga 는 위 코드와 유사한 원리로 동작합니다.
제너레이터 함수의 작동 방식을 이해할 수 있으면 , redux-saga에서 제공하는 여러 유틸 함수를 사용하여 쉽게 액션을 처리할 수 있습니다.
'프론트엔드 > React' 카테고리의 다른 글
[프론트엔드] 리덕스 미들웨어를 통한 비동기 작업 관리[9] (0) | 2022.06.02 |
---|---|
[프론트엔드] 리덕스 미들웨어를 통한 비동기 작업 관리[8] (0) | 2022.06.02 |
[프론트엔드] 리덕스 미들웨어를 통한 비동기 작업 관리[6] (0) | 2022.04.27 |
[프론트엔드] 리덕스 미들웨어를 통한 비동기 작업 관리[5] (0) | 2022.04.26 |
[프론트엔드] 리덕스 미들웨어를 통한 비동기 작업 관리[4] (0) | 2022.04.19 |