Redux开发
我们的项目使用redux来做状态管理,redux是一个全局状态机,统一管理页面所有状态
我们使用 Ducks: Redux Reducer Bundles 的设计建议来定义一个redux模块,我们认为一个模块为一个 duck
所有的 duck 保存在在项目目录 app/ducks 下
设计规则
文件定义
- 必须 使用
export default在index.js中导出reducer - 必须 使用
export在actions.js中导出actions - 必须 使用
export在constants.js中导出action types - 必须 使用
export在selectors.js中导出selector makers - 必须 使用
export default在epic.js中导出epic, 多个epic通过combineEpic合并为一个
action
action 包含
type, type:<string>,action type在constants.js中定义,名称必须为大写payload, type:<any>,action所包含的数据meta, type:<any>,action关联数据,context, 如果是需要epic异步处理,则需要包含resolve,rejecterror, type:<boolean>, 为true时表明这个action是一个error,payload装在着一个·Error对象
epic
每个epic.js中可以包含多个epic,每个epic定义一个异步请求操作
ajax
我们定义一个 ajax 异步请求包含三个action,一个名为loadClusters的action会有三个action:
- loadClusters 发起请求
export const loadClusters = (url, meta = {}) => ({
type: c.LOAD_CLUSTERS,
payload: url,
meta,
});
- loadClustersSuccess 请求成功
export const loadClustersSuccess = (resp, meta = {}) => ({
type: c.LOAD_CLUSTERS_SUCCESS,
payload: resp,
meta,
});
- loadClustersFailure 请求失败
export const loadClustersFailure = (error, meta = {}) => ({
type: c.LOAD_CLUSTERS_FAILURE,
payload: error,
meta,
error: true,
});
对应一个 epic
export const loadClustersEpic = (action$, state$, { ajax }) =>
action$.pipe(
ofType(c.LOAD_CLUSTERS),
mergeMap(({ payload, meta }) =>
ajax(payload).pipe(
map((resp) => {
meta.resolve && meta.resolve(resp);
return a.loadClustersSuccess(resp, meta);
}),
catchError((error) => {
meta.reject && meta.reject(error);
return of(a.loadClustersFailure(error, meta));
})
)
)
);