pile·
프론트엔드·너드팩토리너드팩토리·

react + typescript에 redux-saga 셋팅하기

React 와 TypeScript 프로젝트에 redux 와 redux-saga 를 붙이는 절차를 파일 단위로 정리한 글이다. 덕스 패턴으로 한 파일에 몰아넣던 모듈이 타입 선언 때문에 300줄을 넘기자 5개 파일로 쪼갰고, typesafe-actions 로 액션 생성과 리듀서 작성을 줄였다. 중복 액션 취소는 saga 의 takeLatest 로 해결한다.

핵심 포인트
  • 문제는 TypeScript 도입 후 state 타입 선언이 붙으며 덕스 패턴 모듈 한 파일이 300줄을 넘긴 것이었다. 액션 생성 함수가 5개뿐인데도 그랬다.
  • 모듈 디렉터리를 actions.ts, types.ts, reducer.ts, saga.ts, index.ts 로 분리해 파일명만 봐도 무엇이 정의돼 있는지 드러나게 했다.
  • typesafe-actions 의 createAction 과 ActionType 을 쓰면 액션을 추가해도 타입을 새로 선언할 필요가 없다.
  • 비동기는 createAsyncAction 으로 요청, 성공, 실패 세 액션을 한 번에 만들고 saga 에서 call 로 API 를 호출한 뒤 put 으로 결과를 디스패치한다.
  • takeLatest 를 써서 같은 액션이 진행 중일 때 새 요청이 오면 이전 것을 취소한다. 중복 액션 처리 문제가 이걸로 풀렸다.
상세 정리
  • 설치는 CRA TypeScript 템플릿에 redux, react-redux, @types/react-redux, redux-saga, typesafe-actions 를 더하는 구성이다.
  • 스토어는 combineReducers 로 rootReducer 를 만들고 ReturnType 으로 RootState 타입을 뽑아 컴포넌트에서 재사용한다.
  • 미들웨어 등록을 나중에 편하게 하려고 configureStore.ts 를 미리 분리해둔다.
  • actions.ts 는 액션 타입 상수를 as const 로 선언하고 createAction 으로 생성 함수를 만든다. createAction 은 인수 개수 제한이 없다.
  • types.ts 에는 스토어에 저장될 state 타입과 ActionType 으로 뽑은 액션 타입을 둔다.
  • reducer.ts 는 createReducer 로 switch 대신 객체 형태로 작성한다. 정의된 타입 밖의 값은 애초에 못 쓰기 때문에 값이 없거나 정의되지 않은 데이터로 인한 실수가 줄어든다.
  • API 레이어는 api/test/type.ts 에 파라미터와 응답 타입을, api.ts 에 axios 호출을 두고 응답 타입을 제네릭으로 지정한다.
  • saga.ts 는 제너레이터 함수라 자바스크립트 제너레이터 이해가 전제된다. try 안에서 call 로 API 를 부르고 성공하면 success, 예외면 failure 를 put 한다.
  • 이펙트 정리: call 은 Promise 를 반환하는 함수를 동기적으로 호출하고, fork 는 같은 일을 비동기로 한다. put 은 dispatch 와 동일하다.
  • take 계열 정리: takeEvery 는 호출되는 모든 액션을 수신하고, takeLatest 는 진행 중인 같은 액션을 취소한 뒤 새 요청을 처리하며, takeLeading 은 완료될 때까지 같은 액션 호출을 차단한다.
  • rootSaga 에서 all 로 여러 사가를 병렬 실행하고, configureStore 에서 createSagaMiddleware 로 만든 미들웨어를 applyMiddleware 로 걸고 sagaMiddleware.run(rootSaga) 를 호출한다.
  • 컴포넌트에서는 useSelector 로 스토어 값을 읽고 useDispatch 로 비동기 액션의 request 를 디스패치한다.
  • 저자는 redux-saga 가 유일한 정답이 아니라며 redux-observable 이나 MobX 같은 대안도 있으니 프로젝트 로직에 맞는 걸 고르라고 덧붙인다.
왜 읽나TypeScript 를 얹은 뒤 redux 모듈이 비대해진 프론트엔드 개발자에게 파일 분리 구조와 saga 이펙트 선택 기준을 통째로 보여주는 셋업 가이드.
너드팩토리
너드팩토리 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

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

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

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

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