dva 如何异步获取接口数据
栏目: JavaScript · 发布时间: 6年前
内容简介:dva里的model主要是用来开始处理数据和逻辑的。dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。新建一个一个
说在前面
- 关于redux的框架有很多,这里我用到的是阿里云谦大大的dva( 项目地址 ),这里主要记录下工作中是如何使用dva来异步获取接口数据的。
- 文末更新至20190619
更新(2019.0619)
-
最近发现这篇文章虽然写的很烂,但是很多人都能搜到进来瞅两眼,想着再更新一点吧。主要补充一下
dva的几个关键词的作用
state的作用
- State 表示 Model 的状态数据,通常表现为一个 javascript 对象(当然它可以是任何值);操作的时候每次都要当作不可变数据(immutable data)来对待,保证每次都是全新对象,没有引用关系,这样才能保证 State 的独立性,便于测试和追踪变化。
-
在每一个
model中定义state,用于分模块管理全局状态
effects的作用
-
进行异步操作的地方(ajax...),底层引入了
redux-sagas做异步流程控制,由于采用了generator的相关概念,所以将异步转成同步写法 -
类似于
vuex中的Action,包含异步操作,在vuex中用于提交mutation,从而变更state,在dva中用于提交reducer,用于修改state
Reducer的作用
-
同步方法,唯一可以修改
state的地方,通过effect通过actions传入的值修改state -
类似于
vuex中mutation。
Subscription的作用
- 订阅一个数据源,然后根据条件 dispatch 需要的 action。数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。
payload关键字
-
一般作为参数含义,由UI层通过
dispatch一个payload参数在model文件中使用
call
-
结合
yieldcall发起ajax请求
//getDetailDiscount 接口名 //payload 参数 yield call(getDetailDiscount, payload)
put
-
使用
put关键词提交Reducer
//doDiscounts 一个名字为doDiscounts的同步方法 修改state
yield put({type: 'doDiscounts', payload: response.data});
select
-
在
effect中可以通过select获取model中state -
定义
state
state:{
num:1
}
-
定义
effect
effect:{
*getNum({payload},{select}){
//获取state中的num
const num = yield select(state => state.num)
}
}
-
跨
model获取stateother字段为
model的namespace
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
-
使用
callback非常的不优美,这里官方其实早已提供promise的写法
*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中可以获取到数据
原文首发
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Javascript异步执行结果获取的三种解决方案
- Android利用Handler异步获取子线程中的产生的值
- SpringBoot | :异步开发之异步调用
- 改进异步封装:处理带返回值的异步调用
- 异步发展流程 —— Generators + co 让异步更优雅
- 文件系统与异步操作——异步IO那些破事
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Designing Data-Intensive Applications
Martin Kleppmann / O'Reilly Media / 2017-4-2 / USD 44.99
Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such as scalability, consistency, reliability, efficiency, and maintainability. In addition, w......一起来看看 《Designing Data-Intensive Applications》 这本书的介绍吧!