redux-saga란?
redux-saga는 redux-thunk 다음으로 가장 많이 사용되는 라이브러리다.
redux-thunk는 함수를 디스패치 할 수 있게 해주는 미들웨어였다.
redux-saga는 액션을 모니터링하고 있다가, 특정 액션이 발생하면 이에 따라 특정 작업을 하는 방식으로 사용한다.
redux-saga는 redux-thunk로 못하는 다양한 작업들을 처리 할 수 있다.
- 비동기 작업을 할 때 기존 요청을 취소 처리 할 수 있다
- 특정 액션이 발생했을 때 이에 따라 다른 액션이 디스패치되게끔 하거나, 자바스크립트 코드를 실행 할 수 있다.
- 웹소켓을 사용하는 경우 Channel 이라는 기능을 사용하여 더욱 효율적으로 코드를 관리 할 수 있다.
- API 요청이 실패했을 때 재요청하는 작업을 할 수 있다.
이 외에도 다양한 까다로운 비동기 작업들을 redux-saga를 사용하여 처리 할 수 있다.
참고블로그 : https://react.vlpt.us/redux-middleware/10-redux-saga.html
작업을 실행하기위한 사전세팅
import { takeLatest, call, put, all, fork } from 'redux-saga/effects'
import axios from 'axios'
saga 설치하기
$ npm install redux-saga
saga 세팅하기
const reduxSaga = require('redux-saga')
saga 사용하기 - 기본형
const { createStore, compose, applyMiddleware } = require("redux");
const rootReducer = require('./reducers/index')
const reduxSaga = require('redux-saga')
const middleware = []
const enhancer = process.env.NODE_ENV !== 'production'
? compose(applyMiddleware(...middleware))
: composeWithDevtool(applyMiddleware(...middleware))
const store = createStore(rootReducer, enhancer);
saga의 흐름을 알기위한 구조도
function*으로 작성된 watchCounterUp함수.
action 값을 추적하는 것이 목적인 미들웨어에게 action값을 보내는 함수다.
dispatch( {type:'UP'} )일 경우, UP을 추적한다.
saga effect에서는 function에 *을 붙인다.
redux-saga/effecs에 속해있는 take메서드는 인자값을 두개 사용한다.
첫번째는 action.type : action의 type을 추적하기 위해 사용한다.
두번째는 type을 추적이 되었다면 실행할 function*으로 작성된 함수명을 작성해야한다.
takeLatest는 동일한 명령이 여러번 발생했을때 가장 마지막에 명령을 실행한다.
takeEvery는 동일한 명령이 여러번 발생했을때 모든 명령을 실행한다.
export default function* watchCounterUp(){
yield takeLatest('COUNTER/UP_REQUEST',counterUp) // 이벤트가 발생했을때!
yield takeLatest('COUNTER/DOWN_REQUEST',counterDown)
}
function*으로 작성된 counterUp함수
미들웨어에서 백과 통신하는 API에게 요청을 하고 응답을 받는 함수다.
yield를 만나면 코드 실행이 잠시 멈추는 기능을 이용했으며, yield가 없으면 promise처리가 되어서 pending 상태로 떨어진다.
redux-saga/effecs에 속해있는 call에는 인자값이 두개 들어간다. (동기처리 함수)
첫번째는 사용할 함수명
두번째는 첫번째 인자에 들어간 함수에 대한 인자값이 들어간다.
put은 dispatch와 같은 역할을 한다.
put에 들어온 type으로 action을 실행한다.
function* counterUp(action){
// 여기함수에서 API 내용 작성
try {
console.log('SAGA')
const result = yield call(upAPI,action.payload)
yield put({
type:'COUNTER/UP_SUCCESS'
// dispatch 성공에대한 프로세스
})
} catch (e) {
yield put({
type:'COUNTER/UP_FAILURE'
// dispatch 실패에대한 프로세스
})
}
}
payload값을 받는 upAPI 함수
백과 통신하는 API함수다.
action값을 받았을때 type이 counterUp에서 처리되었다면, payload값은 upAPI에서 처리된다.
비동기적으로 이루어지며 1초 뒤에 무조건 성공이란 결과를 내놓는 코드.
api에 관한 블로그
https://meetup.toast.com/posts/92
https://react.vlpt.us/integrate-api/01-basic.html
async function upAPI(payload){
console.log(payload)
return new Promise( (res,rej)=>{
setTimeout( ()=>{
res(true)
},1000 )
} )
}
내보낸 watchCounterUp을 실행하기 위한 index.js
함수들이 여러개일때 배열에 담아서 필요한 만큼 쪼개서 사용할 수 있는 all
여기까지 와야 비로서 action의 type인 COUNTER/UP의 추적이 끝난다.
import { all } from 'redux-saga/effects'
import takersAll from './takersAll'
import watchCounterUp from './counterSaga' // 가져와서 사용
import userSaga from './userSaga'
console.log( userSaga )
export default function* rootSaga(){
yield all([ watchCounterUp() ])
}
결과
아래와 결과가 나와서 현재 어떤 상태인지 알 수 있다(추적한 결과).
클릭 이벤트로 발생한 COUNTER/UP_REQUEST
중간 middleware에서 발생한 COUNTER/UP_SUCCESS
middleware를 사용한다 = saga를 통해서 내용을 수정하겠다.
'프로그래밍 > react' 카테고리의 다른 글
React Redux - 기본 용어 정리, 실행 흐름, 세가지 원칙 (0) | 2022.05.20 |
---|---|
[220510] Next.js란? (0) | 2022.05.13 |
[220504] 미들웨어) redux-thunk (0) | 2022.05.10 |
[220503] redux ) handleActions, createStore (0) | 2022.05.09 |
[220502] redux로 전역상태 관리하는 기초세팅 (0) | 2022.05.09 |
댓글