React 数据状态管理 Dva

安装 Dva 依赖

通过 npm 安装 dva-cli 并确保版本是 0.9.1 或以上。

cnpm install dva-cli -g

 

定义 Model

新建 model models/products.js :

import Api from 'globals/api/getGoodsDetails';

export default {

  namespace: 'Test', // 命名空间,connect时调用具体空间下的state

  state: {
    stock: 0,
  },

  effects: {
    // umi只支持* yield写法, 类似 ES7的async/await 写法
    *requireData({ payload }, { call, put, select }) {

      const stock = yield select((state) => state.Test.stock)

      const { dm_error, data: productStock } = yield call(Api.getProductStock, {
        ...payload,
      }); // 异步操作,在此处做请求,根据传回参数写回调

      if (+dm_error === 0 && productStock) {
        yield put({ type: 'setProductStock', payload: { productStock } }); // 同步操作,type为reducers中的函数
      }

    },
  },
  reducers: {
    setProductStock(state, { payload }) {
      state.stock = payload.productStock;
    },
  },
  subscriptions: {
    // 注册 model 默认订阅的事件,相当于把一些初始化的dispatch放在此处默认按序执行
    setup({ dispatch }) {
      dispatch({ type: 'setProductStock', payload: { productStock:1 }         
     });
    }
  },
};


这个 model 里:

  • namespace: 当前 Model 的命名空间
  • state: 该 Model 当前的状态。数据保存在这里,直接决定了视图层的输出
  • reducers: Action 处理器,处理同步动作,在此处理State
  • effects:Action 处理器,处理异步动作
  • action:传递的参数对象,内含payload及其它参数
  • payload:传参固定key值,内含自己调用的参数
  • call:执行异步函数
  • put:发出一个 Action,类似于 dispatch
  • select:用于在effect中通过yield获得state的数据

 

reducers中对state数据的处理(嵌套增删改查)

 

使用 model 状态管理

Father 组件 

import React, { Component } from 'react';
import api from '../api';
import { Helmet, connect } from 'umi';
import Son from './son.js'

class Father extends Component {

  // 服务端请求
  static getInitialProps = async ctx => {
    
      const { isServer, history = umiHistory, store } = ctx;
      const { location: { query } } = history;

      // if ( isBrowser() ) return; // 若服务端请求暴露到props的数据满足页面渲染,浏览器可不再次渲染

      const { dispatch, getState } = store;
      const params = { stock: 0, ...query, ctx };

      // 服务端请求,用于渲染meta标签的数据
      let serverData = await dispatch({ type: 'Test/goodsDetails', payload: params });
      // 可以通过dispatch({}).then(()=>{}) 的方式写回调

      return serverData;
  }

  componentDidMount() {

    // connect组件后自动注入dispatch函数到props,用于调用reducers的函数
    // type中的写法为 '命名空间/调用函数'
    // payload为传入的参数,请求无参数时需省略
    // 此处父组件需要调用一次获取初始数据的reducers,子组件connect了model后才能直接使用props数据
    this.props.dispatch({
      type: 'Test/setProductStock',
      payload: { productStock: 123 },
    });

  }

  render() {
    return <div>
      <Helmet>
        <meta property="og:title" content={`服务端渲染动态Meta标签${this.props.serverData.title}`} />
        <title>My Title</title>
      </Helmet>

      <Son></Son>
    </div>
  }
}

export default Father;

son 组件

import React, { Component } from 'react';
import api from '../api';
import { connect } from 'umi';

class Son extends Component {

  componentDidMount() {

  }

  handle(){
    this.props.dispatch({
      type: 'Test/setProductStock',
      payload: { productStock: 123 },
    });
  }

  render() {
    return <div>
      <button onClick={()=>{this.handle()}}>点击设置${this.props.}</button>
    </div>
  }
}

// mapStateToProps函数(约定规范),将state里的数据注入到组件的props
function mapStateToProps(state) {
  const { stock } = state.Test; // 连接刚才定义的命名空间的model进行值的解构
  return { stock };
}

export default connect(mapStateToProps)(Son);

 

详细使用教程:https://www.ahwgs.cn/ruheshiyongdvayufuwuduanjinxingshujujiaohu.html

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值