一、什么是DvaJS
截止 2017.1,最流行的社区 React 应用架构方案如下:
- 路由: React-Router
- 架构: Redux
- 异步操作: Redux-saga
缺点:要引入多个库,项目结构复杂。
dva
是体验技术部开发的 React 应用框架,将上面三个 React 工具库包装在一起,简化了 API,让开发 React 应用更加方便和快捷。
dva = React-Router + Redux + Redux-saga
二、核心概念
核心概念关系图- State:一个对象,保存整个应用状态。
- View:React 组件构成的视图层。
- Action:一个对象,描述事件。
- connect 方法:一个函数,绑定 State 到 View。
- dispatch 方法:一个函数,发送 Action 到 State。
1.State 和 View
-
State
是储存数据的地方,收到Action
以后,会更新数据。 -
View
就是 React 组件构成的 UI 层,从State
取数据后,渲染成 HTML 代码。只要State
有变化,View
就会自动更新。
2.Action
Action
是用来描述 UI 层事件的一个对象。
{
type: 'click-submit-button',
payload: this.form.data
}
3.connect 方法
connect
是一个函数,绑定 State
到 View
。
import { connect } from 'dva';
function mapStateToProps(state) {
return { todos: state.todos };
}
connect(mapStateToProps)(App);
connect
方法返回的也是一个 React 组件,通常称为容器组件。因为它是原始 UI 组件的容器,即在外面包了一层 State
。
connect
方法传入的第一个参数是 mapStateToProps
函数,mapStateToProps
函数会返回一个对象,用于建立 State
到 Props
的映射关系。
4.dispatch 方法
dispatch
是一个函数方法,用来将 Action
发送给 State
。
dispatch({
type: 'click-submit-button',
payload: this.form.data
})
dispatch
方法从哪里来?被 connect
的 Component
会自动在 props
中拥有 dispatch
方法。
三、Model 对象的属性
dva
提供 app.model
这个对象,所有的应用逻辑都定义在它上面。
model
对象有以下属性:
-
namespace
: 当前Model
的名称。整个应用的State
,由多个小的Model
的State
以namespace
为key
合成。 -
state
: 该Model
当前的状态。数据保存在这里,直接决定了视图层的输出。 -
reducers
:Action
处理器,处理同步动作,用来算出最新的State
。 -
effects
:Action
处理器,处理异步动作。
// 创建应用
const app = dva();
// 注册 Model
app.model({
namespace: 'count',
state: 0,
reducers: {
add(state) { return state + 1 },
},
effects: {
*addAfter1Second(action, { call, put }) {
yield call(delay, 1000);
yield put({ type: 'add' });
},
},
});
// 注册视图
app.router(() => <ConnectedApp />);
// 启动应用
app.start('#root');
数据流图1
数据流图2
四、Reducer
Reducer
是 Action
处理器,用来处理同步操作,可以看做是 state
的计算器。它的作用是根据 Action
,从上一个 State
算出当前 State
。
一些例子:
// count +1
function add(state) { return state + 1; }
// 往 [] 里添加一个新 todo
function addTodo(state, action) { return [...state, action.payload]; }
// 往 { todos: [], loading: true } 里添加一个新 todo,并标记 loading 为 false
function addTodo(state, action) {
return {
...state,
todos: state.todos.concat(action.payload),
loading: false
};
}
五、Effect
Action
处理器,处理异步动作,基于 Redux-saga
实现。Effect
指的是副作用。根据函数式编程,计算以外的操作都属于 Effect
,典型的就是 I/O
操作、数据库读写。
function *addAfter1Second(action, { put, call }) {
yield call(delay, 1000);
yield put({ type: 'add' });
}
六、Generator 函数
Effect
是一个 Generator
函数,内部使用 yield
关键字,标识每一步的操作(不管是异步或同步)。
七、call 和 put
dva
提供多个 effect
函数内部的处理函数,比较常用的是 call
和 put
。
-
call
:执行异步函数。 -
put
:发出一个Action
,类似于dispatch
。
网友评论