saga
- apiを使って非同期処理を書く
- actionsで定義したrequest, success, failureのアクションをディスパッチする
import { createUser, FetchError } from '@/common/api';
import { call, put, takeLatest } from 'redux-saga/effects';
import { getType } from 'typesafe-actions';
import * as actions from '@/actions';
function* createUserAsync(
action: ReturnType<typeof actions.createUser.request>
): Generator {
try {
yield call(createUser, action.payload.request);
yield put(actions.createUser.success());
} catch (error) {
if (error instanceof FetchError) {
yield put(actions.createUser.failure({ error }));
}
}
}
export default [
takeLatest(getType(actions.createUser.request), createUserAsync)
];
rootSaga
sagasでexportしたものをrootSagaでyield allする
import { all } from 'redux-saga/effects';
import userSaga from './userSaga';
/**
* RootSaga
*/
export default function* rootSaga() {
yield all([
...userSaga
]);
}
actions
import { createAsyncAction } from 'typesafe-actions';
を使ってsagasでディスパッチする各アクションを作成するコードを書く
import { FetchError } from '@/common/api';
import { CreateUserRequest } from '@/models/request';
import { createAsyncAction } from 'typesafe-actions';
enum CREATE_USER {
REQUEST = '@createUser/request',
SUCCESS = '@createUser/success',
FAILED = '@createUser/failed'
}
export const createUserAction = createAsyncAction(
CREATE_USER.REQUEST,
CREATE_USER.SUCCESS,
CREATE_USER.FAILED
)<{ request: CreateUserRequest }, void, { error: FetchError }>();
reducer
getType({createAsyncActionで作成したaction})で、action.typeを判定しreducerの処理記述
import { ActionType, getType } from 'typesafe-actions';
import * as actions from '../actions';
/** Loadingエフェクトの状態を管理する */
type Action = ActionType<typeof actions>;
export interface LoadingState {
on: boolean;
prediction: boolean;
}
const initialState: LoadingState = {
on: false,
prediction: false
};
export default function loadingReducer(
state: LoadingState = initialState,
action: Action
): LoadingState {
// tslint:disable-next-line:no-duplicate-case
switch (action.type) {
case getType(actions.createUser.request):
return {
...state,
on: true,
prediction: false
};
case getType(actions.createUser.success):
case getType(actions.createUser.failure):
return {
...state,
on: false
};
default:
return state;
}
}
疑問
- saga以外でエラーハンドリングしたい時どうする?
- sagaのargsにcallbackを渡す?