[Redux] Redux-Observable이란?

SeHoony·2021년 10월 7일
2

개념 각인

목록 보기
3/3
post-thumbnail

우리 회사는 상태관리를 위해 "redux-toolkit(slice)""redux-observable(epic)"을 주로 사용하고 있다. slice는 기존의 redux를 더 편하게 사용하기 위한 것으로 이해할 수 있다. 자세한 내용은 slice에 설명해놓았다.

그렇다면 "redux-observable"은 무엇인가? 이는 rxJS를 기반으로 하여 주로 redux middleware 구현 시 사용되고 있는 개념이다. 이번 포스팅에서는 redux-observable을 구현해나가는 일련의 과정에 대해서 서술한다. 마지막으로 rxJS 개념을 알지 못한다면, 이해하기 어려울 수 있으니 참고 바란다.

1. 개괄

redux-observable을 구현해나가는 과정에 대해서 대략적으로 설명하고, 이후 챕터부터 각 단계에서 필요한 개념과 예시 코드를 제시하고자 한다. 가장 중요한 부분은 "1. epic 생성" 부분이며 다른 부분은 하나의 절차에 불과하니 편하게 보면 좋을 거 같다.

  1. set up
  2. epic 생성
  3. export epic : combineEpics 사용(epic이 두 개 이상일 때,)
  4. store 등록
    5-1. createEpicMiddleware() : epicMiddleWare 생성
    5-2. store에 middleWare 추가
    5-3. epicMiddleware.run()

2. SET UP

set up에서는 redux-observable, rxjs, rxjs-operators 라이브러리를 설치한다. 밑의 명령어를 차례대로 터미널에 작성하면 된다.

npm install ——save redux-observable@1.2.0
npm install rxjs
npm install rxjs-operators

3. Epic 생성

3-1. epic이란?

"epic"이란 reducer의 action 하나하나에 매칭되는 middleware이다.
epic내의 구현 흐름은 특정 action이 dispatch 되었을 경우 그것과 매칭되는 epic이 발동하고, epic 내의 순수함수들의 일련의 절차를 거치고 나서, 다시 특정 action을 반환한다. 따라서 epic은 "action in, action out" 형식이라고 생각하면 쉽다.

3-2. epic 생성

예제 코드는 epic(increment_plus3_epic)에 increment라는 action이 들어오면 incrementByValue()라는 액션의 parameter로 3을 넣어 action을 반환하는 과정을 구현한 것이다.

import { Action, Observable } from "redux"
import { ActionsObservable, StateObservable, ofType, combineEpics } from "redux-observable"
import { map, mergeMap } from "rxjs/operators"
import { incrementByValue, increment } from "./counter"

const increment_double_epic = (
  action$: ActionsObservable<any>,
  state$: StateObservable<any>
): any => {
  return action$.pipe(
    ofType(increment), // action$이라는 전체 action stream에서 type이 'increment'인 지 확인
    map((result: any) => {
      return incrementByValue(3) // incrementByValue action으로 다시 반환
    })
  )
}

export const exampleEpic = combineEpics(increment_double_epic)
  • 주의 : action$의 type인 ActionsObservable은 redux-observable 모듈의 1.2.0 버전이다. 현재 시점 기준 npm install ——save redux-observable 작성 시, 2.0.0 버전이 설치되니 주의하자! 이미 2.0.0 버전이 설치되었다면, node-modules에서 redux-observable을 삭제하고 다시 npm install하자!

3-3. epic export

위의 epic들을 store에 등록하기 위해 export 한다. 이 때, epic은 action 당 하나씩 만들어지기 때문에 하나 이상일 수 있다. 따라서 combineEpic을 통해 묶어서 export한다.

export const exampleEpic = combineEpics(increment_double_epic)

4. Store 등록

4-1. createEpicMiddleWare()

만들어 놓은 epic을 store에 middleware로 등록하기 위해서, 여러 미들웨어들을 담을 대표가 필요하다.이를 위해, createEpicMiddleware()를 이용한다.

    const epicMiddleWare = createEpicMiddleware()

4-2. store 등록

앞에서 만든 대표 미들웨어를 store에 동록한다. configureStore로 store을 만들었는데, 혹시 createStore로 store를 만들었다면 약간 방법이 다르니 확인하기 바란다.

export const store = configureStore({
reducer: {
 counter: CounterReducer,
},
// 밑의 한 줄을 추가한다.
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(epicMiddleWare),
})

4-3. epic 등록

편의상 대표 미들웨어라고 부른 것이 store에 등록되었기 때문에, 그 대표 미들웨어에 여러 epic들이 등록되며 자동으로 store에 등록된다. 미리 만들어놓은 epic을 대표 미들웨어에 등록한다.

epicMiddleWare.run(exampleEpic)

4-4. 전체 코드

편의를 위해 store의 전체 코드를 공개한다.

import { configureStore } from "@reduxjs/toolkit"
import { createEpicMiddleware } from "redux-observable"
import CounterReducer from "../features/counter/counter"
import { exampleEpic } from "../features/counter/counterEpic"

const epicMiddleWare = createEpicMiddleware()

export const store = configureStore({
  reducer: {
    counter: CounterReducer,
  },
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(epicMiddleWare),
})

epicMiddleWare.run(exampleEpic)

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

5. Conclusion!

이것으로 epic이 구동되는 간단한 예시를 설명해보았다. 튜토리얼로 만든 것이 아니기 때문에 이렇게 코드를 쓰는 구나하고 이해하는 용도로 쓰면 알맞을 것이다. 그리고 위의 코드의 결과를 말하자면, increment 액션을 보내면 epic이 받아서 incrementByValue(3)을 리턴하고 다시 increment와 incrementByValue(3)이 모두 reducer로 가서 각각 1, 3씩 state를 증가시킨다. 총 4씩 느는 것이다!
하지만 예시가 완전히 적절한 것은 아니다. epic은 middleware로 주로 사용되기 때문에 네트워크 통신이나 비동기 처리에 사용하면 좋을 것이다. 각자의 프로젝트에서 epic을 꼭 한 번 사용해보시길!

profile
두 발로 매일 정진하는 두발자, 강세훈입니다. 저는 '두 발'이라는 이 단어를 참 좋아합니다. 이 말이 주는 건강, 정직 그리고 성실의 느낌이 제가 주는 분위기가 되었으면 좋겠습니다.

0개의 댓글