直接使用redux,要寫很多樣板程式碼,大量的actiontype,actionCreator。
一個非同步的方法要寫三個actiontype,三個actionCreator,十分繁瑣。
下面是本人使用的一種簡化寫法,使用陣列動態生成一些action和actionCreator,具有參考價值。
action-type.js
export const asynctypes = [ 'getCateList', 'getArticleList', 'searchArticles', 'getArticleDetail', ] export const synctypes = [ '@@router/LOCATION_CHANGE' ] export const types = {}; asynctypes.forEach(item => { types[item + '.start'] = item + '.start'; types[item + '.ok'] = item + '.ok'; types[item + '.error'] = item + '.error'; }); synctypes.forEach(item => { types[item] = item; });
synctypes生成同步的actiontype,asynctypes生成非同步的actiontype,字串只在陣列中宣告一次,減少書寫量
action.js
import {asynctypes} from './action-type'; import {createAction} from 'redux-actions'; function fCreateActionsAsync(aType,fCreateAction){ const oResult = {}; aType.forEach(item => { oResult[item + 'Start'] = fCreateAction(item + '.start'); oResult[item + 'Ok'] = fCreateAction(item + '.ok'); oResult[item + 'Error'] = fCreateAction(item + '.error'); }); return oResult; } export default fCreateActionsAsync(asynctypes,createAction);
匯出的是通過asynctypes生成的三個actionCreator的集合,此集合可以直接在bindActionCreators函式中直接使用,
在元件中可以直接呼叫生成的action方法:
元件article.jsx
import acts from 'index/redux/actions'; export default connect( (state,props) => { return {data: state.article.data,currentCate:fCurrentCate(state,props)} }, dispatch => { return {actions: bindActionCreators(acts,dispatch)} } )(Article);
在元件中使用actions.getCateListStart就可以開始一個非同步呼叫了。
start是個開始,專案中使用了redux-saga來自動喚起下面的非同步呼叫,非同步完成後自動呼叫ok或error的action。
//根saga中監控所有的非同步呼叫 export default function* rootSaga(){ yield [ fork(wacthArticleDetail), fork(watchCateList), fork(watchActicleList), fork(watchSearchAtricles) ] } //監控到非同步start呼叫,自動喚起非同步呼叫 function* wacthArticleDetail(){ yield takeEvery(actions.getArticleDetailStart,fGetArticleDetailAsync); } //非同步呼叫結束自動喚起Ok或者error的action function* fGetArticleDetailAsync(action) { try{ const articleId = action.payload.articleId; const article = yield call(getArticleDetail,articleId); yield put(actions.getArticleDetailOk(article)); } catch(err){ yield put(actions.getArticleDetailError(err)) } }