Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

初涉DVA #61

Open
laizimo opened this issue Sep 15, 2019 · 1 comment
Open

初涉DVA #61

laizimo opened this issue Sep 15, 2019 · 1 comment

Comments

@laizimo
Copy link
Owner

laizimo commented Sep 15, 2019

前言

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

正文

由于在项目中是初次尝试使用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版本了,相对比较稳定,如果有兴趣的读者,不妨自己动手尝试一下。

@laizimo
Copy link
Owner Author

laizimo commented Sep 15, 2019

dva官网

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant