redux toolkit + saga

HyosikPark·2021년 2월 26일
0

react + redux

목록 보기
2/2

saga 사용 이유

redux-thunk는 function을 dispatch할 수 있기 때문에 function 로직을 통한 비동기처리 등 간편하게 다양한 작업을 할 수가 있다.

redux-saga는 비동기 처리를 비롯하여 더 많은 작업들을 처리할 수 있게 도와준다.

  1. 비동기 작업 시에 기존 요청을 취소할 수 있다. (여러번 요청을 보낼 경우 마지막 요청에만 반응하도록 할 때에 유용하다.)

  2. 특정 액션을 발생시킬 경우 다른 액션이 디스패치되도록 할 수 있다.

  3. API 요청 실패 시 재 요청 작업이 가능하다.

이 외에도 여러가지 까다로운 작업을 처리할 수 있는 장점이 있다.

제공 API

takeEvery(action, func*)
action을 dispatch할 때마다  func가 실행된다.
          
takeLatest(action, func*)
action을 dispatch할 때 task가 아직 실행중이라면 
작업을 취소하고 다시 task를 실행한다.

take(action)
해당 action이 dispatch될 경우 다음 작업을 실행

call(func, ...args)
동기적 실행 async await에서 await 같은 기능

fork(func, ...args)
비동기 실행

put(action)
dispatch(action)과 동일

delay(ms)
ms 뒤 다음 작업을 실행

all([func1(),func2(),....])
모든 배열 요소 실행

redux toolkit과 연동

// modules/store.ts

import {
  combineReducers,
  configureStore,
  getDefaultMiddleware,
} from '@reduxjs/toolkit';
import todosReducer from './todos';
import createSagaMiddleware from 'redux-saga';
import { all } from 'redux-saga/effects';
import { todosSaga } from './todosaga';

const rootReducer = combineReducers({
 todos: todoReducer,
})

function* rootSaga() {
  yield all([todoSaga()]);
}

const sagaMiddleware = createSagaMiddleware();

const store = configureStore({
  reducer: rootReducer,
  middleware: [...getDefaultMiddleware(), sagaMiddleware],
})

sagaMiddleware.run(rootSaga);

export type RootState = ReturnType<typeof store.getState>;

export default store;

saga를 middleware와 연결한다.

sagaMiddleware.run(rootSaga)은 미들웨어와 연결후에 실행시켜야 제대로 동작한다.

// modules/todosaga.ts

import { PayloadAction } from '@reduxjs/toolkit';
import { delay, put, takeLatest } from 'redux-saga/effects';
import { toggleTodo, toggleTodoAsync } from './todos';

function* toggleSaga(action: PayloadAction<number>) {
  yield delay(1000); // 1초 뒤 다음 동작 실행
  yield call(func, ...args) // 동기적으로 함수 실행
  yield fork(func, ...args) // 비동기 함수 실행
  yield put(toggleTodo(action.payload)) //dispatch toggleTodo
}

export function* todoSaga() {
  yield takeLatest(toggleTodoAsync, toggleSaga)
}

takeLatest이므로 toggleTodoAsync action을 dispatch 하는 경우 toggleSaga func task가 실행중이라면 작업을 취소하고 다시 시작한다.

0개의 댓글