写这篇文章主要是将自己学会的知识再表达出来,自己虽然理解了这块知识,但是是否能用自己的话再讲出来,那又是另外一种境地,只有能自己讲述后才算完成转化。 传送门
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 = () => <div>Hello dva</div>;
// 创建应用
const app = dva();
app.model(model)
// 注册视图
app.router(() => <App />);
// 启动应用
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一般用于监听路由变化,当满足某些要求时,可以触发一些事件