1.1.1 • Published 6 years ago
redux-enhancer v1.1.1
Redux Enhancer
What is it?
Tired of always copy pasting a lot of redux boilerplate everytime you create a new store, or handle an async action?
- Automaticaly generate the state of your async actions!
- Automaticaly generate reset store
But in depth?
Enhance your redux modules:
- Automaticaly handling the start, loading, error or success, and reset Redux phases of your async calls
- Four action types will be automaticaly created such as:
{ REQUEST: { SIGNUP: { START: `USER.REQUEST.SIGNUP.START`, SUCCESS: `USER.REQUEST.SIGNUP.SUCCESS`, FAILED: `USER.REQUEST.SIGNUP.FAILED`, RESET: `USER.REQUEST.SIGNUP.RESET`, }, }, }
- Two states will be automaticaly added such as:
{ requests: { LOGIN: { loading: true, failed: false, }, }, }
- Two selectors corresponding to the state will be automaticaly generated such as:
{ signupLoading: (state) => state.user.requests.LOGIN.loading, signupFailed: (state) => state.user.requests.LOGIN.failed, }
- Four action types will be automaticaly created such as:
- Adding a
RESET_STORE
action to your different stores re-initializing your stores to theirdefaultState
- An action type and action creator are generated:
{ RESET_STORE: 'RESET_STORE' } { resetStore: () => ({ type: 'RESET_STORE' }) }
- Your enhanced reducer will handle automaticaly your stores reset when dispatching the action
- An action type and action creator are generated:
How to use? Full example here
In your redux module file(s) import the necessary enhancers:
import { enhanceActionTypes, enhanceActionCreators, enhanceDefaultState, enhanceReducer, enhanceSelectors } from 'redux-enhancer'; ...
Create two variables, a string for the name of your store, an array of string in caps for your async calls:
... const storeName = 'USER'; const asyncActionsNames = ['SIGNUP']; ...
Enhance your action types by passing the
storeName
andasyncActionsNames
:... const actionTypes = { ...enhanceActionTypes(storeName, asyncActionsNames), LOGOUT: 'LOGOUT', }; ...
Enhance your action creators by passing the
storeName
,apiActionsNames
andactionTypes
:... const actionCreators = { ...enhanceActionCreators(storeName, asyncActionsNames, actionTypes), requestSignupStart: signupInfo => ({ type: actionTypes.REQUEST.SIGNUP.START, payload: signupInfo, }), }; ...
Enhance your default state by passing the
asyncActionsNames
:... const defaultState = { ...enhanceDefaultState(asyncActionsNames), }; ...
Create your normal reducer and enhance it afterwards by passing the
storeName
:... const basicReducer = (state, action) => { switch (action.type) { case actionTypes.REQUEST.SIGNUP.SUCCESS: return { ...state, token: action.payload.token, }; default: return state; } }; const reducer = (state = defaultState, action) => enhanceReducer(storeName, state, action, defaultState, basicReducer); ...
Enhance your selectors by passing the
storeName
andasyncActionsNames
:... const selectors = { ...enhanceSelectors(storeName, asyncActionsNames), token: (state) => state.user.token, }; ...
Use your newly generated actions and state inside your app:
// In a container? const mapStateToProps = (state) => ({ signupLoading: selectors.signupLoading(state), signupFailed: selectors.signupFailed(state), }); const mapDispatchToProps = { startSignup: actionCreators.startSignup, resetSignup: actionCreators.resetSignup, }; // With a saga for instance function* signupSaga(action) { try { const { email, password, nickname } = action.payload; const { token } = yield call(api.signup, email, password, nickname); yield put({ type: actionTypes.REQUEST.SIGNUP.SUCCESS, payload: { token } }); } catch (err) { yield put({ type: actionTypes.REQUEST.SIGNUP.FAILED, payload: { err } }); } }
Contributing
To be filled
Todo
- Rename the package to make it more explicit and less generic
- Check the licence
- Find a way to flow type the automaticaly created actions and selectors