redux-unfold-saga-toolkit
v1.0.2
Published
A more user-friendly, headache-free redux-saga middleware
Maintainers
Readme
redux-unfold-saga-toolkit
A more user-friendly, headache-free redux-saga middleware.
This library is inspired by redux-unfold-saga.
Getting started
Install
npm install --save redux-unfold-saga-toolkitor
yarn add redux-unfold-saga-toolkitThis library is required redux-saga and immer
Usage example
- action
import { createAction } from 'redux-unfold-saga-toolkit';
const fetchPosts = createAction('FETCH_POSTS');
dispatch(
fetchPosts(
{ category: 'HOT' },
{
onBegin: () => {
// Do something before the query
setLoading(true);
},
onFailure: (error: Error) => {
// Do something in case of caught error
},
onSuccess: (posts: IPost[]) => {
// Do something after the query succeeded
},
onFinish: () => {
// Do something after everything is done
setLoading(false);
},
},
),
);- saga
import { call, takeLatest } from 'redux-saga/effects';
import { unfoldSaga } from 'redux-unfold-saga-toolkit';
function* takeQueryPosts(action: UnfoldSagaActionType): Iterable<SagaIterator> {
yield unfoldSaga({
action: action,
handler: function* () {
const data = yield call(ApiPost.listPost);
return data;
},
});
}
function* defaultSaga() {
yield takeLatest('QUERY_POSTS', takeQueryPosts);
// yield takeLatest(fetchPosts, takeQueryPosts);
// yield takeLatest(fetchPosts.type, takeQueryPosts);
}- reducer
import { createReducer, createStoreAction } from 'redux-unfold-saga-toolkit';
const fetchPosts = createStoreAction('FETCH_POSTS');
const initState = {
posts: [],
error: null,
loading: true,
};
const postReducer = createReducer(initState, (builder) => {
builder.addCase<void>(fetchPosts.begin, (state, action) => {
state.loading = true;
});
builder.addCase<void>(fetchPosts.finish, (state, action) => {
state.loading = false;
});
builder.addCase<IPost[]>(fetchPosts.success, (state, action) => {
state.posts = action.payload;
});
builder.addCase<Error>(fetchPosts.failure, (state, action) => {
state.error = action.payload;
});
});API
Table of Contents
- createActionTypeOnBegin
- createActionTypeOnFinish
- createActionTypeOnSuccess
- createActionTypeOnFailure
- createAction
- createStoreAction
- createReducer
- unfoldSaga
createActionTypeOnBegin
Create onBegin action type
Parameters
key
Examples
import { createActionTypeOnBegin } from 'redux-unfold-saga-toolkit';
createActionTypeOnBegin('DO_SOMETHING'); // DO_SOMETHING_BEGANReturns string ${key}_BEGAN
createActionTypeOnFinish
Create onFinish action type
Parameters
key
Examples
import { createActionTypeOnFinish } from 'redux-unfold-saga-toolkit';
createActionTypeOnFinish('DO_SOMETHING'); // DO_SOMETHING_FINISHEDReturns string ${key}_FINISHED
createActionTypeOnSuccess
Create onSuccess action type
Parameters
key
Examples
import { createActionTypeOnSuccess } from 'redux-unfold-saga-toolkit';
createActionTypeOnSuccess('DO_SOMETHING'); // DO_SOMETHING_SUCCEEDEDReturns string ${key}_SUCCEEDED
createActionTypeOnFailure
Create onFailure action type
Parameters
key
Examples
import { createActionTypeOnFailure } from 'redux-unfold-saga-toolkit';
createActionTypeOnFailure('DO_SOMETHING'); // DO_SOMETHING_FAILEDReturns string ${key}_FAILED
createAction
Create an action for real life usage inside or even outside of a component, no dispatch to reducer
Parameters
type
Examples
import {createAction} from 'redux-unfold-saga-toolkit';
const fetchPosts = createAction<IPostPayload>('FETCH_POSTS');
dispatch(
fetchPosts(
{category: 'HOT'},
{
onBegin: () => {
// Do something before the query
setLoading(true);
},
onFailure: (error: Error) => {
// Do something in case of caught error
},
onSuccess: (posts: IPost[]) => {
// Do something after the query succeeded
},
onFinish: () => {
// Do something after everything is done
setLoading(false);
},
},
),
);Returns UnfoldSagaActionCreator action
createStoreAction
Create an action for real life usage inside or even outside of a component, dispatch to reducer with automatic create action type
Parameters
type
Examples
// Action
import {createStoreAction, createReducer} from 'redux-unfold-saga-toolkit';
const fetchPosts = createStoreAction<IPostPayload>('FETCH_POSTS');
dispatch(
fetchPosts(
{category: 'HOT'},
{
onBegin: () => {
// Do something before the query
setLoading(true);
},
onFailure: (error:Error) => {
// Do something in case of caught error
},
onSuccess: (posts:IPost) => {
// Do something after the query succeeded
},
onFinish: () => {
// Do something after everything is done
setLoading(false);
},
},
),
);
// Reducer
const initState = {
posts: [],
error: null,
loading: true,
};
const postReducer = createReducer(initState, (builder) => {
builder.addCase<void>(fetchPosts.begin, (state, action) => {
state.loading = true;
});
builder.addCase<void>(fetchPosts.finish, (state, action) => {
state.loading = false;
});
builder.addCase<IPost[]>(fetchPosts.success, (state, action) => {
state.posts = action.payload;
});
builder.addCase<Error>(fetchPosts.failure, (state, action) => {
state.error = action.payload;
});
})Returns UnfoldSagaActionCreator action
createReducer
A utility function that allows defining a reducer as a mapping from action type to case reducer functions that handle these action types. The reducer's initial state is passed as the first argument.
Parameters
initialStatebuilderCallback
Examples
// Action
import {createStoreAction, createReducer} from 'redux-unfold-saga-toolkit';
const fetchPosts = createStoreAction<IPostPayload>('FETCH_POSTS');
dispatch(
fetchPosts(
{category: 'HOT'},
{
onBegin: () => {
// Do something before the query
setLoading(true);
},
onFailure: (error:Error) => {
// Do something in case of caught error
},
onSuccess: (posts:IPost) => {
// Do something after the query succeeded
},
onFinish: () => {
// Do something after everything is done
setLoading(false);
},
},
),
);
// Reducer
const initState = {
posts: [],
error: null,
loading: true,
};
const postReducer = createReducer(initState, (builder) => {
builder.addCase<void>(fetchPosts.begin, (state, action) => {
state.loading = true;
});
builder.addCase<void>(fetchPosts.finish, (state, action) => {
state.loading = false;
});
builder.addCase<IPost[]>(fetchPosts.success, (state, action) => {
state.posts = action.payload;
});
builder.addCase<Error>(fetchPosts.failure, (state, action) => {
state.error = action.payload;
});
})Returns any State of reducer has immer
unfoldSaga
Common saga helper that unifies handling side effects into only one standard form
Parameters
bodyUnfoldSagaHandlerTypebody.actionUnfoldSagaActionType Actionbody.handlerFunction Main handler function. Its returned value will become onSuccess callback param
Examples
import {SagaIterator} from 'redux-saga';
import {call, takeLatest} from 'redux-saga/effects';
import {unfoldSaga} from 'redux-unfold-saga-toolkit';
import {fetchPosts} from './action';
// Saga function
function* takeQueryPosts(action: UnfoldSagaActionType): Iterable<SagaIterator> {
yield unfoldSaga({
action: action,
handler: function* () {
const data = yield call(ApiPost.listPost);
return data;
},
});
}
or
// Async function
function* takeQueryPosts(action: UnfoldSagaActionType): Iterable<SagaIterator> {
yield unfoldSaga({
action: action,
handler: async function () {
const data = await ApiPost.listPost();
return data;
},
});
}
function* defaultSaga() {
yield takeLatest('FETCH_POSTS', takeQueryPosts);
// yield takeLatest(fetchPosts, takeQueryPosts);
// yield takeLatest(fetchPosts.type, takeQueryPosts);
}Returns SagaIterator SagaIterator
License
MIT © hungnguyen2809
