pile·
프론트엔드·트렌비트렌비·

리덕스 사가(Redux Saga)란 무엇인가?

트렌비 프론트엔드가 리덕스 미들웨어를 정리하면서 redux-saga 를 왜, 어떻게 쓰는지 설명한 글이다. 리듀서가 순수 함수여야 한다는 원칙 때문에 부수 효과는 미들웨어가 맡아야 하고, saga 는 제너레이터로 비동기 흐름을 동기 코드처럼 읽히게 만든다. 주요 이펙트 함수와 실제 보일러플레이트 적용 구조까지 다룬다.

핵심 포인트
  • 리덕스는 단방향 데이터 흐름을 구현한 Flux 아이디어를 따르며 상태를 담는 Store, 상태를 조작하는 Reducer, 액션을 전달하는 dispatch, 변화 신호인 Action 으로 이뤄진다.
  • 세 원칙 중 리듀서를 순수 함수로 작성해야 한다는 항목이 미들웨어의 존재 이유다. 리듀서에서 부수 효과를 가진 함수를 실행하면 원칙을 깬다.
  • 미들웨어는 dispatch 함수를 감싸며 서로 체이닝되고, 모든 미들웨어를 통과한 뒤에야 액션이 리듀서로 전달된다.
  • redux-saga 는 제너레이터를 써서 비동기 흐름을 동기 코드처럼 읽고 쓰고 테스트할 수 있게 한다. 기존 요청 취소나 여러 API 순차 호출 같은 까다로운 작업에 유용하다.
  • saga 가 yield 하는 것은 실행 결과가 아니라 함수와 인자를 담은 명령 객체인 이펙트다. 미들웨어가 그 객체를 검사해 타입에 따라 어떻게 수행할지 결정한다.
상세 정리
  • 문제의 출발점은 리액트 컴포넌트가 외부 상태를 props 로만 받을 수 있어, 계층이 깊어지면 상태 흐름 추적과 의존 컴포넌트 확인이 어려워진다는 것이다.
  • 구성 요소를 하나씩 짚는다. Store 는 모든 상태를 저장하며 리듀서를 인자로 받고, 리듀서는 초기 상태와 액션을 받아 어떤 상태를 바꿀지 지정하며, dispatch 가 액션과 상태 데이터를 리듀서로 넘긴다.
  • Action 은 type 필드로 어떤 변화가 필요한지 알리는 신호 객체이며 변경에 필요한 데이터를 함께 담을 수 있다.
  • 미들웨어 세 가지를 비교한다. redux-promise 는 payload 가 Promise 면 응답이 올 때까지 기다렸다 결과를 리듀서에 넘겨 단순한 비동기에 유용하고, redux-thunk 는 객체 대신 함수를 반환할 수 있어 가장 널리 쓰이며, redux-logger 는 리듀서 실행 전후를 로그로 비교하게 해준다.
  • 제너레이터는 function 뒤에 별표를 붙여 만들고 호출하면 이터레이터 객체가 반환된다. next 메서드로 실행하고 yield 지점에서 멈추는 일시 정지와 재시작이 saga 흐름 제어의 기반이다.
  • 미들웨어 등록 순서는 createSagaMiddleware 로 미들웨어를 만들고 applyMiddleware 에 인자로 넘긴 뒤, run 으로 진입점인 루트 사가를 실행하는 것이다.
  • 이펙트 함수 정리가 실용적이다. fork 는 매개변수로 받은 함수를 비동기로 실행해 블로킹 없이 새 작업을 만들고, call 은 비동기 함수면 완료될 때까지 기다려 블로킹이 발생한다.
  • put 은 액션을 디스패치하며, 워커 사가에서 API 성공과 실패에 따라 상태를 반영할 때 주로 쓴다.
  • takeEvery 는 액션이 디스패치될 때마다 새 작업을 fork 하므로 중복 실행이 문제없는 경우에 쓰고, takeLatest 는 실행 중이던 작업을 취소하고 새 작업을 분기해 최신 데이터만 받게 한다.
  • select 는 리듀서의 특정 상태를 saga 로 가져오는데 블로킹이 발생해 값을 얻은 뒤에야 다음 작업이 진행된다.
  • fork 가 반환한 태스크 객체를 cancel 에 넘기면 실행 중인 작업을 취소할 수 있고, 취소된 경우에도 워커 사가 내부에서 그에 대한 처리를 할 수 있다.
  • 트렌비는 react-boilerplate 구조를 써서 컨테이너 컴포넌트마다 고유 key 를 만들고 useInjectReducer 와 useInjectSaga 로 스토어에 리듀서와 사가를 주입한다. 루트 사가를 따로 만들지 않고 컴포넌트 안에서 watcher saga 를 실행하는 방식이다.
왜 읽나redux-thunk 로 버티다 요청 취소나 순차 호출 같은 요구를 만난 프론트엔드 개발자에게 saga 의 동작 원리와 이펙트 선택 기준을 개념부터 정리해주는 글.
트렌비
트렌비 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2