dva的model

dvamodel数据层

dva 首先是一个基于reduxredux-saga的数据流方案,简化开发体验,可以理解为是一个轻量级的应用框架,今天主要总结一下他的model模块,这个模块我理解的是主要用来处理数据,就是所谓的数据层,model主要包含五个部分

  • namespace:命名空间
  • state:数据的初始化,优先级低于 dva()opts.initialState
  • reducers:同步更新state,唯一可以更改state的地方,通过action触发
  • effects:异步更新state,不直接修改state,通过action触发
  • subscriptions:订阅数据源(数据源可以是当前的时间,服务器的 websocket连接, keyboard输入,geolocation变化,history路由变化等等),然后根据需要 dispatch相应的 action
  1. namespace
export default {
    namespace: 'asn',
};
  1. state
export default {
    state: {
        initdata:'我是初始值'
        asnResult:null,
    },
};
  1. reducers
export default {
    reducers: {
        updateState(state, { payload }) {
            return {
                ...state,
                ...payload,
            };
        },
    },
};
  1. effects
export default {
    effects: {
        *getAsnData({ payload }, { call, put }) {
            // 其中Service.getAsnData是一个axios的请求,payload是请求的参数
            // export function getAsnData(asnid) {
                // return get(`/asns/summaries/${asnid}`);
            //}
            const { data = {} } = yield call(Service.getAsnData, payload.asnid);
            yield put({ 
                type: 'updateState',
                payload:{ 
                    initdata:'初始值改变了',
                    asnResult:data
                }
            });
        },
    },
};
  1. subscriptions
// 应用场景,比如当我进入某一个页面,然后发送一个ajax,除了在react的生命周期componentDidMount中去发送以外,还可以在subscriptions中通过监听路由的变化去dispacth一个action
subscriptions: {
		sendAjax({ dispatch, history }) {
			history.listen(({ pathname }) => {
				if (pathname === '/asns') {
					dispatch({
						type: 'getAsnData',
					});
				}
			})
		},
        keyEvent({dispatch}) {
          key('⌘+up, ctrl+up', () => { dispatch({type:'add'}) });
        }
	}

model是处理数据的地方,页面是应用数据的地方,那么如何把modelpage连接起来,dva提供connect 方法。这个 connect就是 eact-reduxconnect

下面案例的整个数据流向:

  • 通过点击事件getAsnDatadispatch一个action(asn/getAsnData)触发effets里面的getAsnData方法

  • 然后effets里面的getAsnData方法通过yield call去调用后端的接口Service.getAsnData,拿到返回数据data

  • 然后通过reducer(updateState)去更新state

  • 最后页面通过命名空间connect连接到相应的model,在通过this.props拿到数据,展示在页面

import React from 'react';
import { connect } from 'dva';
import { Button } from 'antd';

// @装饰器模式
@connect(({ asn:{ asnResult },loading }) => ({
    asnResult,
    // dva-loading可以自动处理loading状态
    asnloading:!!loading.effects['asn/getAsnData'],
}))
class ASN extends Component {
    state = {}

	getAsnData = () => {
        const { dispatch } = this.props;
        dispatch({
            type: 'asn/getAsnData',
            payload:{
                asnid:xxxxxx
            }
        })
    }

	render() {
        const { asnResult,asnloading } = this.props;
        return(
        	<Button 
                onClick={this.getAsnData}
                loading={asnloading}
            >
                获取asn的数据---->{asnResult}
            </Button>
        )
    }
}

export default ASN



// 非装饰器模式
export default connect(({ asn:{ asnResult },loading }) => ({
   	asnResult,
    // dva-loading可以自动处理loading状态
    asnloading:!!loading.effects['asn/getAsnData'],
}))(ASN);

​ 当然dva中的数据流向不只上面异步一种,还有同步,以及通过监听某些数据源和行为,dva官网用一张图把他的数据流转表达的非常清楚
在这里插入图片描述

​ 如上图所示,不管通过同步异步还是其他,共同的都是通过dispatch发起一个action,如果是同步的那么直接走reducer去改变state,如果是异步的通过先触发effects,再流向reducer,最终去更新state,还有一种是通过subscriptions去监听某些数据源,然后dispatch一个action

猜你喜欢

转载自blog.csdn.net/YMX2020/article/details/106674097
dva