Redux-Saga

ohoho·2023년 3월 21일
0

React

목록 보기
8/12

Redux-Saga란?

  • Redux-Saga란 비동기 작업을 처리하기 위한 미들웨어이다.
  • 액션을 모니터링을 하며 특정 액션이 발생했을때 미리 정해둔 로직에따라 특정 작업이 이루어지는 방식이다.
    (특정 Javascript를 실행하거나, 다른 Action을 Dispatch 할수도있고, 현재 State를 불러올 수 도있다.)
  • 순수함수들로 로직을 처리할 수 있으며, 순수함수로 이루어지다보니 사이드 이펙트도 적고 테스트 코드를 작성하기에 유리하다.
  • 제너레이터라는 특수한 형태의 함수로 구현된다.
  • Generator는 함수를 구현할 때, 함수의 실행을 특정 구간에 멈추게 하거나 원하는 시점으로 돌아가게 할 수 있다.
  • 결과값을 여러번 리턴하게 할 수 있다.
  • 제너레이터 함수를 만들때는 function* 이라는 키워드를 사용한다.
  • 제너레이터 함수를 통해 객체가 반환된다.
- 비동기 작업 진행시, 기존 요청 취소
- 특정 액션이 발생했을때 이를 구독하고 있다가 다른 액션을 디스패치하거나 특정 자바스크립트 코드 실행
- API요청 실패시 재요청 가능
- 효율적인 코드관리

리덕스 사가 사용 가이드

import { call, put, takeEvery } from 'redux-saga/effects';
import * as FIIL_ME_IN from '../api/FIIL_ME_IN';
import { createRequestActionTypes } from '../api/createRequestSaga';
// 필요한 모듈을 불러와줍니다. 

/* 
1. 사용할 액션 타입을 지정해준다. 
( 리덕스 내에서 State를 업데이트할때는 항상 액션 타입을 지정해줘야한다.)
*/

const [
	LOGIN_USER,
    SUCCESS,
    FAILED
] = createRequestACtionTypes('userLogin/LOGIN_USER')


/* 
2. 해당 타입이 발동될 수 있는 함수를 만든다.
(dispath()를 이용하여 발동시킨다.)
*/

/* userLogin.js*/
export const loginUserList = (userData) => ({
	type : SOME_TYPE,
  	payload : userData,
})

/*container.jsx*/
const dispatch = dispatch();
dispatch(loginUserList());

/*
* container.jsx에서 다른 유저를 get요청을 통해 가져온뒤
* 해당 데이터로 리듀서 상태를 업데이트 시키는 LOGIN_USER라는 액션을 수행시키는 예제이다.
*
*
* 해당 타입이 수행해야하는 api요청이 GET라면
* export const loginUserList = () = ({
* 	type : SOME_TYPE,
* })
*
*
* POST요청과 같이 특정 데이터를 인자로 전달해야하는 상황이라면
* export const loginUserList = (userData) => ({
* 	type : SOME_TYPE,
* 	payload : userData,
* })
* 위처럼 인자에 데이터를 넣은뒤 payload에 넣어 줄 수 있다.
*
*/

export function* loadUserLoginSaga(action){
	try {
    	const loadResult = yield call(loadUserApi.loadUserAsync, action.payload);
      
      yield put({
      	type : SUCCESS,
        payload : loadResult,
      });
    } catch (e) {
    	yield put({
        	type : FAILED,
            payload : e,
        });
    }
}

export function* userLoginSaga(){
	yield takeEvery(LOGIN_USER,loadUserLoginSaga);
}

/*
* userLoginSaga 함수는 감시자 역할을 한다.
* 해당 함수는 LOGIN_USER라는 액션 타입의 수행 여부를 감시하며, 만일 수행됐다면 두번째 인자에 있는 loadUserLoginSaga란 콜백함수를 실행시킨다.
*
* const loadResult = yield call(loadUserApi.loadUserAsync, action.payload);
* call 은 async await 와 비슷한 역할을 한다.
* 첫번째 인자의 함수 수행이 끝난 후에 loadResult란 변수에 할당을 한다.
* 두번째 인자는 post요청시 payload로 넣어준 값이 들어간다.
* (get요청이라면 두번째 인자는 필요없음)
* loadUserApi.loadUserAsync 란 api요청을 보내는 함수가 수행되어 loadResult에 정상적으로 값이 할당 되었다면,
* yield put(dispatch()와 흡사)에서 성공하면 SUCCESS타입을 실패라면 FAILED을 수행시킨다.
*/

export default function SOME_REDUCER(state = {}, action){
	switch(action.type){
      case SOME_TYPE :
        return {
        	...state,
        };
      case SUCCESS :
        return {
        	...state,
          SOME_KEY: action.payload,
        };
      case FAILED :
        return {
        	...state,
          SOME_ERROR: SOME_VALUE,
        };
        
      default:
        return state;
    }
}

/*
* 위 코드는 모든 타입들의 중앙 처리 장소인 reducer 이다.
* 주목해야 할 부분은 첫번째 인자로 전달되는 state와 아래의 switch / case 부분이다.
* reducer의 state는 따로 임의의 값들로 구성된 객체로 선언한뒤 인자로 전달할 수 있지만,
편의를 위해 인자 자체에서 빈 객체로 선언해둔 상태이다.
* 그렇기에 해당 리듀서의 초기값은 빈 객체이며, 사가 함수에서 성공 / 실패 여부에 따라 SUCCESS,FAILED로 나뉘게 되고 그에 맞는 state 업데이트가 이뤄지게 된다.
*/

참조

0개의 댓글