初涉DVA

979 阅读4分钟

前言

最近在项目的开发过程中,接触了DVA。这个相对来说新鲜的React框架,它将一系列的React项目有关的库进行了一个打包以及封装,提供了一套它自己的API,方便开发者使用。同时,它基于Redux提供了一整套的数据流解决方案,对那些苦苦纠缠于状态管理的开发者而言,是一个不错的选择。

正文

由于在项目中是初次尝试使用dva这个框架,所以,使用上面大多都是基本的。下面是一些使用方面的心得。

首先,在dva框架中,有一个model的概念。这个有些类似以前的MVC框架的概念,Model作为一类模型,管理一些内部的state状态,以及一系列的行为。我们可以通过下面的例子来进行分析,如下:

export default {
  namespace: 'user',

  state: {
    userInfo: {},
    companyCardList: [],
    personalCardList: []
  },

  effects: {
    *queryBaseInfo({ payload, callback }, { call, put }) {
      const res = yield call(API.queryBaseInfo, payload);
      if (res && res.data) {
        yield put({
          type: 'getBaseInfoSuccess',
          payload: res.data
        });
        if (callback) {
          callback(res.data);
        }
      }
    }
  },

  reducers: {
    getBaseInfoSuccess(state, { payload }) {
      return {
        ...state,
        companyCardList: [],
        personalCardList: [],
        ...payload
      };
    }
  }
}

这是一个名为User的Model,顾名思义,它管理着相关用户的一些信息状态。除了state里面的一些相关变量(这些变量会在相关的组件里面使用到),此处还有effects和reducers。

官方介绍:

namespace是全局state里面的一个key,根据key来获取相关的state

state是整个model相关state的一个初始值

effects是来处理一些异步的行为的

reducers接收行为,同步更新state

这样将一个相关Model中的行为都统一放置在一起,state统一放置在一起,方便开发者进行管理。同样,会带来的一个问题就是,随着项目越来越大,Model越来越多,越来越臃肿。所以,合理进行Model的划分,何时才需要使用到Model变得至关重要,此处不做过多的展开。

Model定义完成之后,就是与组件之间的链接了,只有链接完成之后,才可以在组件中使用相关的Model行为,更新state。

我们同样使用一个例子来进行分析,如下:

import React, { Component } from 'react';
import { connect } from 'dva';

class Nav extends Component {
  constructor(props) {
    super(props);

    this.state = {
      activeIndex: ''
    };
  }

  componentWillMount() {
    this.props.dispatch({
      type: 'home/merchantLogin',
      payload: {}
    });
  }

  render() {
    const { activeIndex } = this.state;
    const merchantInfo = this.props.home.merchantInfo || {};
    return (
        ...
    )
  }
}

export default connect(({ home }) => ({
  home
}))(Nav);

其中我们可以看到,dva框架提供了一个connect的API,来进行Model与组件之间的绑定,这里会将一个命名空间为home的Model作为一个变量返回,然后在connect方法中,将其赋值给Nav组件的props。关键步骤就是这里的赋值。

这样,我们就可在组件中使用this.props.home.merchantInfo这个变量了,这个变量是home Model的state里面的merchantInfo的初始值。同时,可以在组件的render过程中使用这些数值。

链接完成之后,我们还在上述的例子中看到了一个dispatch这个方法,这个就是dva框架提供的另一个API,来触发Model中的一个相关行为。通过一张官方的解释图,我们可以清晰的还原整个数据流的过程,如下:

dva概念

通过图中我们可以看到一切的行为的起点是dispatch,然后经过相关的行为,去对应的Model里面执行相关行为函数,然后更新state,在反馈到相关的组件中。这样子的数据流是否比以前乱糟糟的组件间的状态好很多了呢。

其实,接触过一些RxJS的思想,发现大家在处理数据流的过程中,总是会有异曲同工之处。

总结

第一次尝试dva,体验上面还是不错的。因为本次的项目是一个比较复杂的中台系统,才会想到去使用这样一套框架对状态进行管理。同样的,dva作为一套数据流的解决方案,还是有着很多的缺点的,尤其是Model的使用,如果是简单的组件,尽量少使用Model进行管理,组件内部状态管理和外部状态管理,两者相结合,才能减少Model的滥用问题。现在的dva已经发展到2版本了,相对比较稳定,如果有兴趣的读者,不妨自己动手尝试一下。

如果你对我的文章感兴趣的话,欢迎关注我的微信公众号。

qrcode_for_gh_6176010a708d_258.jpg