ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ReactJS - Redux-Saga
    ReactJS 2022. 7. 15. 10:28

    리덕스의 사이클

    - 비동기적인 것들은 어떻게 해결할 것인가?

        → Middleware

     

    Middleware

    1. Redux-thunk

        ㆍ추적이 힘들고, 테스트가 어렵다

        ㆍ패턴을 직접 만들어야하고 , 직접 지켜야한다

        ㆍAction creator의 반환이 Action object가 아니다.

     

    2. Redux-saga

        ㆍ관리하기 쉽고, 테스트가 쉽다

        ㆍ적당한 패턴으로 서비스로직을 쉽게 만들 수 있다

        ㆍAction creator의 반환은 Action object


    Redux-saga

    Concept

    1. side effect ( 부수 효과 )

    - 비동기 요청, 브라우저 캐시, 로컬 스토리지

    - (자바스크립트) 코드가 외부 세계에 영향을 주거나 받는 것

    2. Generator

    - Runner는 generator를 받을 수도 있고, generator를 직접 호출할 수 있다

    EX1

    import { put, takeEvery, delay } from 'redux-saga/effects'
    
    export default function* rootSaga() {
        yield takeEvery('INCREMENT_ASYNC', incrementAsync )
    }
    
    export function* incrementAsync() {
        yield delay(1000)
        yield put({ type: 'INCREMNET' })
    }

    - INCREMNET_ASYNC 액션이 발생하면

    - incrementAsync 함수 실행 ( 1초를 기다리고 INCREMENT 액션 Dispatch )

     

    - Effect는 미드웨어에 의해 수행되는 명령을 담고 있는 평범한 자바스크립트 객체라고 생각

    - Saga는 Effect를 yield하고, Middleware는 Effect를 처리한다.

    EX2

    function* fetchSaga() {
        const result = yield call(api.fetchA, arg1, arg2)
        
        console.log(result)
    }

    - call은 async-await의 await같은 역할을 한다.

     

    Effect를 yield하면, Middleware에서 처리가 끝날때까지 기다려야 할까? ㄴㄴ

    - Blocking 작업이 끝날 때까지 기다려주지만, Non-blocking은 작업이 끝날 때까지 기다려주지는 않는다.

     

    - fork : 다른 saga를 전달( 다른 공간에서 실행될것 )


    Orchestration

    ( 주로 자동화 개념? )

    1. " takeLastest " Effect

    - 어떤 작업의 요청이 들어왔을 때 앞선 요청이 끝나지 않았다면 전부다 취소

    -  마지막에 들어온 작업만 완료를 시키겠다.

     

    2. 파일업로드 시 Progress 

    - channel 사용

    ( → 웹소켓 공부이후에 볼 것... )

     


    redux-saga의 헬퍼함수

    1. delay

    - 설정된 시간 이후에 resolve를 하는 Promise 객체를 리턴

    2. put

    - 특정 액션을 dispatch 한다 ( ex: put({type: 'INCREMENT'}) )

    3. call

    - 주어진 함수를 실행한다 ( ex: call( delay, 1000 ) )

    - 미들웨어가 Promise의 resolve를 기다리게 하기 때문에 동기함수 ( 주로 api 호출 )에 사용

    4. take

    - 들어오는 특정 액션을 처리한다. 한번 실행되고 이벤트가 삭제

    5. takeEvery

    - 모든 리퀘스트에 대해 take를 실행

    function* watchFetchData() {
        yield takeEvery('FETCH_REQUESTED', fetchData)
    }

    - 만약 fetchData task가 시작되었을때 이미 이전 task가 실행중이라면, 이전 task는 자동으로 취소

    6. fork

    - 백그라운드에서 task가 실행

    - 나중에 다시 볼 것! ( 두번째 참고자료 )

    7. cancel

    - fork된 task를 취소 시킨다 ( ex: yield cancel(task) )

    - 제너레이터를 finally 구간으로 가게한다. 이때 취소한 task하위에 다른 task가 포함되어 있다면 모두 취소

    8. all

    - 이 함수를 사용해서 제너레이터 함수를 배열의 형태로 넣어주면, 제너레이터 함수들이 병행적으로 동시에 실행되고, 전부 resolve 될 때까지 기다린다.( Promise.all 과 비슷하다 )

     

     

     

     

    참조 :

    1. https://www.youtube.com/watch?v=UxpREAHZ7Ck

    2. https://leego.tistory.com/entry/Redux-saga%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90#-%EF%B-%-F%E-%--%A-%--callback%--%ED%--%A-%EC%--%--%EB%A-%BC%--action%--payload%EB%A-%-C%--%EB%--%--%EA%B-%B-%--%EC%--%--%--%EC%-E%--%EB%-B%A--

    3.  https://react.vlpt.us/redux-middleware/10-redux-saga.html

     

     

    추가 공부 자료 :

    1.https://blog.nerdfactory.ai/2021/01/02/setting-redux-saga.html

    2. https://github.com/velopert/ts-react-redux-tutorial

    3. https://github.com/piotrwitek/typesafe-actions#1-basic-actions

    4. https://redux-saga.js.org/docs/introduction/GettingStarted/

     

     

     

    댓글

Designed by Tistory.