写这篇文章主要是将自己学会的知识再表达出来,自己虽然理解了这块知识,但是是否能用自己的话再讲出来,那又是另外一种境地,只有能自己讲述后才算完成转化。
dva是什么
dva 是阿里体验技术部开发的 React 应用框架,命名是根据守望先锋中的任务D.va而来。 主要用于解决组件之间的通行问题, 在以前react项目中解决数据流问题会引入redux,又由于redux没有异步操作,所以需要引入redux-saga或redux-thunk,这样的缺点就是 引入多个库,致使项目结构复杂。而现在:
dva = React-Router + Redux + Redux-saga
将上面三个 React 工具库包装在一起,简化了 API,让开发 React 应用更加方便和快捷。
- 了解dva之前可以先去了解redux-saga.
dva的最简结构:
import dva from 'dva';const App = () =>Hello dva;// 创建应用const app = dva();app.model(model)// 注册视图app.router(() =>);// 启动应用app.start('#root');复制代码
数据流图
核心概念
- State:一个对象,保存整个应用状态
- View:React 组件构成的视图层
- Action:一个对象,描述事件
- connect 方法:一个函数,绑定 State 到 View
- dispatch 方法:一个函数,发送 Action 到 State
state和view
state是用于数据存储保存全局状态。view是react组件构成的UI层,当state变化时会触发ui层视图的变化。
Action和dispatch
action是用于描述一个事件的一个对象
{ type: 'submit-form-data', payload: formData}复制代码
dispatch则用来发送Action到State
connect
connect 是一个函数,绑定 State 到 View,connect 方法返回的也是一个 React 组件,通常称为容器组件,是用于生成State到Prop的映射
// 第一种写法这里使用来修饰器@@connect((state) => { return { dept: state.dept, version: state.version, };})// 第二种写法connect(({ state}) => ({state}))(App);复制代码
Model
dva中的model是所有的应用逻辑都定义在里面
model的栗子?:
export default { namespace: 'modelName', state: { num: 0 }, subscriptions: { setup({dispatch,history}){ return history.listen(({pathname, query})=>{ dosomething.... }) } } effects: { *addAfter1Second({payload}, { call, put, select }) { yield call(delay, 1000); yield put({ type: 'add' , payload: 10}); const num = yield select(state => state.modelNmae.num); console.log(num) }, }, reducers: { add(state, action) { return{ ...state, num: action.payload } }, },}复制代码
model对象的属性由namespace,state, effect,reducers,subscriptions组成。
namespace和state
namespace当前 Model 的名称。整个应用的 State,由多个小的 Model 的 State 以 namespace 为 key 合成,当在ui层触发变化时,可以利用namespace来区分触发那个model的方法。从而改变state.
dispatch({ type: 'modelname/add', payload: 10})复制代码
数据保存在state,直接决定了视图层的输出.
effects和reducers
effects和reducers都是action的处理器,不同的是reducers处理的是同步的action,effects处理的是异步的action,effects是基于 redux-saga实现,effect是一个Generator函数,内部使用yield关键字,标识每一步的操作。effect提供了供内部使用的三个方法。
- call: 执行异步函数,一般用于请求数据
- put: 相当与dispatch,发出一个action,触法一个同步的action
- select: 可以用于获取全局的状态state
subscriptions
subscriptions一般用于监听路由变化,当满足某些要求时,可以触发一些事件