리덕스 사가에 대한 이해와 사용법

2020. 10. 22. 13:27웹 프론트엔드 개발 노하우/리액트 노하우

리덕스에서 상태의 변경은 모두 동기적으로 일어납니다. 따라서 미들웨어를 통해 스토어 상태 변경 프로세스 중간에 비동기 로직을 끼워 넣어야만 API 요청에 따른 상태변경을 수행할 수 있습니다.

그러한 미들웨어가 redux-thunk 나 redux-saga 같은 리덕스 생태계 패키지입니다.

리덕스 사가가 제공하는 createSagaMiddleware() 함수를 실행시켜 반환된 객체를 미들웨어로 등록시키고, run 메서드를 실행하면 리덕스에 사가를 적용할 수 있습니다.

 

 

리덕스 사가로 할 수 있는 일

리덕스 사가는 단순히 비동기 처리를 위해 만들어진 패키지가 아닙니다. 그건 그냥 미들웨어로도 충분히 가능합니다. 리덕스 사가는 사이드 이펙트를 더 쉽게 관리하고 더 효과적으로 실행하며 더 쉽게 테스트하고 더 나은 에러 처리를 할 수 있게 만들기 위해 제작되었습니다. 이를 위해 리덕스 사가는 비동기 작업을 세가지 종류로 세분화하였습니다.

REQUEST : 비동기 요청

SUCCESS : 비동기 요청 성공

ERROR : 비동기 요청 실패

이 세가지가 등록된 액션이 실행되면, 리덕스 사가는 이를 감지해서 특정 제네레이터 함수가 수행되도록 합니다.

 

  • takeLatest 함수 : 스토어에 들어오는 액션을 감시하고 있다가 특정 액션이 발생된 것을 알면 특정 함수를 수행하도록 해줌(누군가가 실수로 버튼을 연달아 2번 누르는 경우와 같은 경우에 서버로 같은 요청이 연달아 2번 가지 않도록 하기 위해 마지막 액션 하나만 유효하게 인정한다)
  • takeEvery 함수 : takeLatest 와 비슷한데, 마지막 액션 하나만 유효하게 보는 것이 아니라 모든 액션을 유효하게 처리한다.
  • call 함수 : 인자로 받은 함수를 실행한다. 전달 받은 함수가 프라미스를 반환하는 경우, 프라미스가 처리될 때까지 제너레이터를 중지시킨다. 프라미스가 리졸브되면 그 값으로 제네레이터를 다시 시작하고, 리젝트 되면 제네레이터는 에러를 던지는 동작을 한다.
  • fork 함수 : call 함수와는 다르게, 함수가 프라미스를 반환하더라도 그게 처리될 때까지 기다리지 않는다. 순서 없이 수행해야 하는 비동기 함수를 호출할 때 사용한다
  • put 함수 : 액션을 스토어로 디스패치하는 역할을 한다(결국 스토어의 상태를 변경하는 것은 리듀서의 몫이다).

 

이렇게 되면 흐름은 간략하게 말하면 다음과 같습니다.

 

  1. 컴포넌트는 요청 액션을 디스패치해서 스토어에게 비동기 요청을 알린다.
  2. 사가는 스토어로 들어오는 액션을 감시하고 있다가(takeLatest 함수를 통해) 요청 액션을 발견하면 특정 함수를 실행한다. 이 함수는 비동기 로직을 제어하는 제네레이터이며, call 함수로 API를 호출하고 결과를 받는다. 그리고 put 함수로 받은 데이터를 처리하는 액션을 발행한다.
  3. 리듀서는 이 액션을 받아 스토어를 갱신한다