Dva 是什么呢?官方的定义是:dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
简单理解,就是让使用 react-redux 和 redux-saga 编写的代码组织起来更合理,维护起来更方便。
之前我们聊了 redux、react-redux、redux-saga 之类的概念,大家肯定觉得头昏脑涨的,什么 action、reducer、saga 之类的,写一个功能要在这些 js 文件里面不停的切换。
dva 做的事情很简单,就是让这些东西可以写到一起,不用分开来写了。比如:
app.model({
// namespace - 对应 reducer 在 combine 到 rootReducer 时的 key 值
namespace: "products",
// state - 对应 reducer 的 initialState
state: {
list: [],
loading: false,
},
// subscription - 在 dom ready 后执行
subscriptions: [
function (dispatch) {
dispatch({ type: "products/query" });
},
],
// effects - 对应 saga,并简化了使用
effects: {
["products/query"]: function* () {
yield call(delay(800));
yield put({
type: "products/query/success",
payload: ["ant-tool", "roof"],
});
},
},
// reducers - 就是传统的 reducers
reducers: {
["products/query"](state) {
return { ...state, loading: true };
},
["products/query/success"](state, { payload }) {
return { ...state, loading: false, list: payload };
},
},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
以前书写的方式是创建 sagas/products.js, reducers/products.js 和 actions/products.js,然后把 saga、action、reducer 啥的分开来写,来回切换,现在写在一起就方便多了。
比如传统的 TODO 应用,用 redux + redux-saga 来表示结构,就是这样:
saga 拦截 add 这个 action, 发起 http 请求, 如果请求成功, 则继续向 reducer 发一个 addTodoSuccess 的 action, 提示创建成功, 反之则发送 addTodoFail 的 action 即可。
如果使用 Dva,那么结构图如下:
整个结构变化不大,最主要的就是把 store 及 saga 统一为一个 model 的概念(有点类似 Vuex 的 Module),写在了一个 js 文件里。增加了一个 Subscriptions, 用于收集其他来源的 action,比如快捷键操作。
app.model({
namespace: "count",
state: {
record: 0,
current: 0,
},
reducers: {
add(state) {
const newCurrent = state.current + 1;
return {
...state,
record: newCurrent > state.record ? newCurrent : state.record,
current: newCurrent,
};
},
minus(state) {
return { ...state, current: state.current - 1 };
},
},
effects: {
*add(action, { call, put }) {
yield call(delay, 1000);
yield put({ type: "minus" });
},
},
subscriptions: {
keyboardWatcher({ dispatch }) {
key("⌘+up, ctrl+up", () => {
dispatch({ type: "add" });
});
},
},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
之前我们说过约定优于配置的思想,Dva 正式借鉴了这个思想。