简单介绍一下
近期在做react项目时,看到项目中数据的公共存储用的Dva.js,整体的代码结构看起来和vuex差不多,这两天趁着刚忙完,利用工作之余的时间空隙,大致了解了dva的基础理论,代码结构应用,参考着其他优秀的技术大神博主,今天也做个大致的整理。
大致了解Dva:什么是dva呢?dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。dva主要是为了降低组件之间耦合,简化元素,来降低开发难度。
数据流向:数据的改变发生通常是通过用户交互行为或者浏览器跳转行为来触发。
这里图简单解读一下,通过dispatch 来触发action。如果是同步行为 通过 reducer 来改变 state的状态,异步行为的话,通过 effect 来触发 reducer 再改变 state。
1)这里的 Effect 指的是副作用,根据函数式编程,计算以外的操作都属于 Effect。
Dva概念:先上一段demo代码
app.model({
namespace: 'todo',
state: [],
reducers: {
add(state, { payload: todo }) {
// 保存数据到 state
return [...state, todo];
},
},
effects: {
*save({ payload: todo }, { put, call }) { // 第一个参数要传的值,第二个是Generator函数中的方法
// 调用 saveTodoToServer,成功后触发 `add` action 保存到 state
yield call(saveTodoToServer, todo); // 第一个值函数名称,第二个值传递的参数
yield put({ type: 'add', payload: todo }); // 第一个值reducer名称,第二个值传递的参数
},
},
subscriptions: {
setup({ history, dispatch }) {
// 监听 history 变化,当进入 `/` 时触发 `load` action
return history.listen(({ pathname }) => {
if (pathname === '/') {
dispatch({ type: 'load' });
}
});
},
},
});
1) namespace 该 dva 的命名,它就相当于一个 key ,通过这个 dva 命名来使用,处理 state 等一些列数据。
举个例子在组件中使用:
import { connect } from 'dva';
function mapStateToProps(state) {
return {
todos: state.todos
};
}
connect(todo)(mapStateToProps); //dva的命名:todo
2) State 是储存数据的地方,收到 Action 以后,会更新数据。
这里的 Action 是用来描述 UI 层事件的一个对象。
{
type: 'add',
payload: todo
}
3)select
Dva
中Effects
函数的固定传参- 用于拿到
model
中state
的数据,需要注意的是,state
后面跟命名空间namespace
的值
const data = yield select((state) => state.namespaceName.valueName);
4) call
Dva
中Effects
函数的固定传参- 第一个参数是一个异步函数,
payload
是参数,可以通过call
来执行一个完整的异步请求,又因为yield
的存在,就实现了异步转同步的方案
const { data } = yield call(queryInterface, payload);
5) put
- 发出一个 Action,类似于 dispatch
Dva
中Effects
函数的固定传参
yield put({ type: 'add', payload: todo });
本文章参考 http://t.csdn.cn/OnSgX