一、dva 介绍

dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。dva = React-Router + Redux + Redux-saga

二、dva 概念

数据流向:
	数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过 dispatch 发起一个action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变State,所以在dva中,数据流向非常清晰简明,参考下面的图

三、Models

通过 dva()可以产生一个app实例,该app实例上有这么几个重要的api
## 1.	State
	初始化数据的,可以是任意的值,类似于vuex中的state模块/redux中reducers模块中的initState
## 2.	Action
	action就是一个普通的js对象,它是改变 State 的唯一途径。action 必须带有 type 属性指明具体的行为,其它字段可以自定义,类似	  于redux中的action
## 3.	Dispatch
	dispatching function 是一个用于触发 action 的函数
## 4.	Reducer
	相当于redux中的reducer,根据之前的状态和action生成最新的状态
## 5.	Effect
	用于异步操作,底层是使用了redux-saga
## 6.	Subscription
	用于订阅一个数据源,然后根据条件 dispatch 需要的 action
## 7.	namespace
	model的命名空间,同时也是他在全局 state 上的属性,只能用字符串,不支持通过 . 的方式创建多层命名空间

四、Router

dva 实例提供了 router 方法来控制路由,使用的是react-router
在 dva 中,通常需要 connect Model的组件都是 Route Components(路由组件),组织在/routes/目录下,而/components/目录下则是纯组件(非路由组件)

五、相关 Api

dynamic:
	解决组件动态加载问题的 util 方法
    使用:
		import dynamic from 'dva/dynamic';

        const UserPageComponent = dynamic({
          app,
          models: () => [
            import('./models/users'),
          ],
          component: () => import('./routes/UserPage'),
        });
	## app: dva 实例,加载 models 时需要
	## models: 返回 Promise 数组的函数,Promise 返回 dva model
	## component:返回 Promise 的函数,Promise 返回 React Component
生命周期钩子:
	1.onError(捕获错误)
    2.onAction(action被dispatch触发)
	3.onStateChange(state改变时触发,可用于同步 state 到 localStorage,服务器端)
	4.onReducer(封装reducer执行)
	5.onEffect(封装effect执行)
	6.onHmr(模块热替换相关)
	7.extraReducers(指定额外的 reducer)
	8.extraEnhancers(指定额外的StoreEnhancer)
app实例上的api
	1.app.model(model) // 注册model
	2.app.unmodel(namespace) // 取消model注册,清理 reducers, effects 和 subscriptions。subscription 如果没有返回 								unlisten 函数,使用 app.unmodel 会给予警告
	3.app.replaceModel(model) // 替换model为新model,只在app.start()之后可用.会保留旧的state状态
	4.app.router((router) => routerConfig) // 注册路由表
	5.app.start(selector) // 启动应用