dva开发参考资料
https://blog.csdn.net/TurkeyCock/article/details/88427158
https://www.yuque.com/flying.ni/the-tower/tvzasn#d6fa1d0c
[https://github.com/gege-circle/home/issues/783

](https://github.com/gege-circle/home/issues/783)
搞懂 DvaJS 原理
[https://github.com/gege-circle/home/issues/783

](https://github.com/gege-circle/home/issues/783)
https://github.com/dvajs/dva-knowledgemap
image.png

dva是什么

一个基于 redux,redux-saga, react-router,react-router封装的的数据流方案

  • 内置了 ,和fetch,expres的 mock方案
  • 最新的是 react-router-dom代替 react-router
  • dva特性:就是把一个路由下的state、reducer、sagas 写到一块了,清晰明了

dva将所有与数据操作相关的逻辑集中放在一个地方处理和维护,让代码更加清晰可控
设计model时将不同类型的业务需求数据操作分开处理,便于维护

redux的缺点

  • 不够扁平化
  • 页面配套(action、reducer)过于繁琐、复杂

dva概念

6个 API,redux用户可以快速上手

  • reducers
  • effects
  • models
  • subscriptions

5个API

  1. const app = new dva({options});
  2. app.use() // Hooks plugin
  3. app.models() // ModelObject
  4. app.router() // Function
  5. app.start() // HTMLElement

8个概念

  1. State 整个应用的数据层,初始state在model中定义,由model state组成全局state
    1. namespace,model state在全局state中所用到的key
  2. action
  3. model
  4. reducers
  5. effects
  6. subscription
  7. router
  8. RouteComponent 业务组件

dva特点

支持,HMR,模块热替换
基于 babel-plugin-dva-hmr(https://github.com/dvajs/babel-plugin-dva-hmr)
实现 components、routes 和 models的 HMR

dva插件机制

dva-loading,自动处理 loading的 true & false,不用一遍遍地写 showLoading 和hideLoading

dva数据流向

image.png
改变数据通过 dispatch一个 action

  • 同步,直接通过 reducers 改变 state
  • 异步,先触发 effects 然后, effects里面 put(action) 流向 reducers 最终改变 State

    1. const action = { type: 'init', payload: {} }
    2. dispatch(action);

    如果:dispatch的type,在 reducers和 effects都有,会同时触发

  • 先触发 reducers

  • 后触发 effects,

    1. export default {
    2. namespace: 'list',
    3. state: {},
    4. reduers: {
    5. init() {},
    6. },
    7. efffects: {
    8. *init() {}
    9. },
    10. subscriptions: {
    11. setup({ dispatch, history}){
    12. }
    13. },
    14. }

    业务建模思维:单向数据流动过程

  1. 从设计model state开始进行抽象数据
  2. 完成component后,将组件和model建立关联
  3. 通过dispatch(action),在reducer中更新数据完成数据同步处理
  4. 通过 effects数据异步处理,然后调用 reducer更新全局state

dva将所有与数据操作相关的逻辑集中放在一个地方处理和维护,让代码更加清晰可控
设计model时将不同类型的业务需求数据操作分开处理,便于维护

redux workflow
image.png

分层思维

为了让数据流更易于维护,redux分成了store,reducer,action等模块,各司其职,软件开发也是一样

  • routes
  • models
  • service

routes

routes里面存放页面组件,负责和用户直接打交道

  • 渲染页面
  • 接受用户的操作和输入,事件交互

路由决定进入url渲染哪些Component
routes也就是日常开发的核心,代码编写都在这个目录里面
routes/index.js hooks组件

  1. import React, { useEffect } from 'react';
  2. import { connect } from 'dva';
  3. function App({dataSource, loading, dispatch}) {
  4. useEffect(() => {}, [
  5. dispatch({type: 'list/init', payload: {page: 1, limit: 10}});
  6. ]);
  7. return (
  8. <div>
  9. </div>
  10. )
  11. }
  12. function mapStateToProps(state) {
  13. return {
  14. dataSource: state.list.dataSource,
  15. loading: loading.effects['list/init'],
  16. }
  17. }
  18. export default connect(mapStateToProps, null)(App);
  • 需要 connect Model的组件都是 RouteComponents
  • /components/目录下则是纯组件,尽量不要 connect链接 models,通过 props传递数据

models

负责处理数据,处理页面业务逻辑,负责页面的数据状态

  • 数据清晰,
  • ajax的异步逻辑判断

每个路由都对应一个model,
这个model掌管这个路由的所有状态(action、state、reducer、sagas),
组件想改变状态dispatch({type, action}) type名字就行了
image.png

models相关概念

  • namespace,一个大型应用可能包含多个 model,通过 namespace 区分
  • state
    • 只能有 reducers修改 state
  • dispatch(action)
  • reducers,修改 state
    • reducer 是一个纯函数,接受当前的state 及一个 action对象,返回新的 state
    • action 对象里面可以包含数据体(payload)作为入参,需要返回一个新的 state
    • reducer 是唯一可以更新 state
  • effects
    • 处理异步操作,和API接口的业务逻辑
    • 不可以修改 state,要通过触发 action 调用 reducer 实现对 state 的操作
  • subscriptions 订阅

models模板

  1. export default {
  2. namespace: 'count',
  3. state: {
  4. },
  5. reducers: {
  6. add(state, action) {
  7. },
  8. },
  9. effects: {
  10. *asyncAdd(action, effect) {
  11. const { call, put } = effect;
  12. yield call(delay, 1000);
  13. yield put({ type: 'add' });
  14. },
  15. },
  16. }

action格式

  1. { type: 'add', payload: todo }

services

http的 API接口对象,进行纯粹的接口管理