React

dva 如何异步获取接口数据

2018-10-31  本文已影响0人  w候人兮猗

说在前面

更新(2019.0619)

state的作用
effects的作用
Reducer的作用
Subscription的作用
payload关键字
call
//getDetailDiscount 接口名
//payload 参数
yield call(getDetailDiscount, payload)
put
//doDiscounts 一个名字为doDiscounts的同步方法 修改state
yield put({type: 'doDiscounts', payload: response.data});
select
 state:{
     num:1
 }
 effect:{
     *getNum({payload},{select}){
         //获取state中的num
         const num = yield select(state => state.num) 
     }
 }

other字段为modelnamespace

 effect:{
     *getOtherNum({payload},{select}){
         //获取state中的num
         const num = yield select(state => state.other.num) 
     }
 }

这里是正文

第一步、定义model

dva里的model主要是用来开始处理数据和逻辑的。
dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。

新建一个一个model/users.js

export default {
  namespace: 'users',
  state: [],
  reducers: {
     doSearch (state, { payload}){
      return {
        ...state,
        searchRsp: payload.data,
      }
    },
  },
  effects:{
  * handleGetSearch({payload, searchRspCallBack}, {call, put}) {
      LogTag('****************************handleGetSearch req*************', payload);
      const response = yield call(getSearch, payload);
      LogTag('****************************handleGetSearch rsp*************', response);
      if (response.status === 200 && response.data.status === 0) {
        searchRspCallBack(response.data.result)
      } else if (response.status === 200 && response.data.status === 1) {
        message.error(response.data.msg)
        yield put({
          type: 'doSearch',
          payload: response.data,
        });
      }
      
  },
  subscriptions :{
      
  }
};

新建ApiService.js文件

import request from '../utils/request';
import {stringify} from 'qs';
/*
* 搜索
* */
export async function getSearch(params) {
  return request(`/search?${stringify(params)}`);
}

这里我主要在effects 定义了一个handleGetSearch方法,
这个方法简单理解:

1、paload是接口的参数,这里打印一下
2、searchRspCallBack是一个回调方法,
  主要是在接口正常调用之后将响应内容在页面层使用
3、yield call(getSearch, payload);是一个异步调用接口参数的方法
4、上述中的if判断主要是说在接口响应到的数据为我与后台正确定义的返回码才进行相应的操作,
比如这里我跟后台约定的是status === 0正常 status === 1 打印后台返回的错误信息
5、searchRspCallBack(response.data.result)
  调用传过来的回调将接口返回数据作为参数传进去

reducers方法:用于执行同步操作,改变state等

return {
    ...state,
    searchRsp: payload.data,
    }
改变model中state的searchRsp值为接口返回的响应内容

第二步、使用model中的方法

model中异步获取数据的方法定义好之后如何使用呢?

this.props.dispatch({
      type: 'users/handleGetSearch',
      payload: {
        keywords: this.state.searchText,
        limit: this.state.limit
      },
      searchRspCallBack: this.handleSearchRspCallBack
})

handleSearchRspCallBack = (rsp)=>{
    LogTag(rsp)
}


这是dva中使用dispatch调用model中方法的写法,注意在使用此方法之前要先使用 connect将model与component连接起来,如果你熟悉 redux,这个 connect 就是 react-redux 的 connect 。

这里使用注解的方法使用connect

@connect(({users, loading}) => ({
  users,
}))

上述dispatch的简单解释:

1、type为要调用的哪个model中的哪个方法,

2、payload为传的参数,这里传了一个keyword与limit数量过去

3、searchRspCallBack: this.handleSearchRspCallBack的意思是将本地的一个方法作为参数传递到model中,
如果model中正确响应之后将响应的内容作为参数传递到这个方法中,
然后我本地写一个handleSearchRspCallBack方法用来接收响应
这样我在component层就可以拿到接口响应的内容了

这是我用来获取接口异步数据的方法第一种,还有一种就是之前在model中执行了reducer同步方法将接口返回的数据保存在了model中的state里面,在componentWillReceiveProps钩子函数也可以拿到我们需要的响应

componentWillReceiveProps(nextProps){
    if(nextProps){
      LogTag(nextProps.users.searchRsp)
    }
  }

上述中nextProps.users.searchRsp就是接口返回的值了

简单的总结

1、先在model中定义一个方法用来执行异步调用接口的方法,可以直接使用回调方法的方法将响应作为参数回调,也可以使用同步reducer的方法将数据保存在state中,后面component层去取model中state的值

2、两种方法都可以获取到异步调用接口返回的响应,第一种好需要定义一个回调方法,第二种获取model中state值需要定义state,在不同的场景使用不同的方法

文章补充:2019.6.1

    *handleUpdateBasicInfo({ payload, user }, { call, put, select }){
      const response = yield call(postUpdateBasicInfo, payload);
      if (response && response.status === 0) {
        return response.data
      }
    },
    //这里在effect中直接return 我们想知道的结果
    
    handleUpdateBasicInfo = (params) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'user/handleUpdateBasicInfo',
      payload: {
        ...params,
      },
    }).then(res=>{
      console.log('res',res)
    })
  };
  //这里then中可以获取到数据


原文首发

上一篇下一篇

猜你喜欢

热点阅读