Rashomon511/MyBlog

前端数据流管理方案之二——Dva

Opened this issue · 0 comments

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');

数据流图

image

核心概念

  • 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一般用于监听路由变化,当满足某些要求时,可以触发一些事件