ant design pro 的模块组织实践
首先我要赞叹 antd 是这个地球上最好的 React 组件库,没有之一。在我心目中的第二名是 semantic-ui ,但落后 antd 不是零星半点
antd 解决了视图层面的重复劳动的问题,使得不同团队、不同项目甚至不同公司之间不再重复的开发相同功能的组件。而 antd pro 则解决了项目级别的重复劳动,你不再纠结于使用哪一种数据流框架,不需要再手动创建项目目录以及安装依赖,antd pro 的脚手架一键为你解决一切问题,antd pro 本质上是由 dvajs 和 roadhog (没错,他们借用了游戏「守望先锋」中两位英雄的名称)组成。前者是 redux, redux-saga 等框架的集合,并且以新的语法进行了封装;后者同样是对 webpack 封装之后更易用的脚手架工具
我个人在使用 antd pro 完整开发项目之后的感受是(但并没有和他们团队确认过),ant design pro 是 react + redux 的最佳实践的集成。因为篇幅有限,无法对这个脚手架框架做详细的介绍,这里重点聊一聊 dva 里的某部分实践,看看是否和我们之前描述的有异曲同工之妙
dva 的实践 首先 dva 中没有了 action 和 store 的概念,而是把两者合二为一设定为「model」,也就是我们熟悉的「领域模型」的概念,数据都存储在 modal 中,如果需要改动数据也需要通过 model 的方法。我们可以看一看一个名为 jobs 的 model:
import { queryAll as queryAllJobs } from "../services/job";
export default {
namespace: "jobs",
state: {
data: [],
pagination: {}
},
effects: {
*fetch({ payload }, { call, put }) {
const response = yield call(queryAllJobs, payload);
yield put({
type: "save",
payload: response
});
}
},
reducers: {
save(state, action) {
const { data, pagination } = action.payload;
return { ...state, ...{ data, pagination } };
},
reset() {
return {
data: [],
pagination: {}
};
}
}
};
因为 dva 集成了 redux 与 redux-saga,所以你能在以上代码中代码中看到这两个类库的用法的影子,是不是既熟悉又陌生。我在这里稍微做一些解释:
第一行来自 ../services/jobs
的方法 queryAllJobs
很明显是一个返回 promise 的用于请求接口的方法,比如 fetch('/api/jobs')
。因为 services 目录出卖了它,把远程请求放在 services 目录中通常是约定俗成的。
接下来你会看到 namespace
字段,它对当前这个 model 进行了命名。这也是与原始 redux 中非常不一样的地方,在原始 redux 的实践中,我们并没有明确每一块数据的业务所属,而这里使用了「命名空间」对它加以限定。
state
和 reducers
大家都非常熟悉了,前者定义了这个 model 下具体的数据有哪些,后者则用于修改这些数据。这里的 reducer 规则与 redux 里是一致的,讲究 pure,讲究 immutable data
effects
可以大家不太熟悉,它其实就是我们常说的「副作用」,比如最常见的异步操作。例如当我们需要在组件中请求 jobs 的信息时,调用:
this.props.dispatch({
type: 'jobs/fetch',
payload: query,
});
它并不直接修改 state, 仍然是通过 action 间接触发 reducer 对 state 进行修改。