利用Dva调用接口
在前端的开发中,总是会涉及到调用接口这个问题。我作为一名前端的小白,谈一下自己对于调用接口的理解。
这是Dva的官网https://dvajs.com/guide/。
dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
在实际开发中会遇到这样的情况,比如某个接口需要在多个不同的页面被多次调用,总是一遍遍的的调用接口的API会很麻烦,这时候就可以单独把这一块拎出来写。dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。
官方提供的一些核心概念如下:
-
State:一个对象,保存整个应用状态
-
View:React 组件构成的视图层
-
Action:一个对象,描述事件
-
connect 方法:一个函数,绑定 State 到 View
-
dispatch 方法:一个函数,发送 Action 到 State
我在代码开发中实际是这样做的。首先在services文件夹里面写调用接口的函数。
export async function GetShortnoteTemplate() { return Authorizationaxios({ // {API_PREFIX}里面存放的是地址,根据编译环境的需要可以随时更换地址 url:`${API_PREFIX}/api/v1/returnOrderConfig/note/search`, method:'GET', }); }
然后在models文件夹里面对数据进行些处理。
//把我们定义的services引入进来 import {GetShortnoteTemplate , AddShortnoteTemplate , DeleteShortnoteTemplate} from '@/services/shortnoteTemplate'; const shortnote = { //命名空间,也是全局上的属性,于解决多个models之间的互相干扰的问题,我们存储所有数据都会在这个空间下。 //namespace: 'global' 说明以下此处的dva命名空间为 global,即你调用的时候需要采用 global.XXX 的形式 namespace:'shortnoteTemplate', // 初始值 state:{ // 初始值为空的 shortnote_data:[], }, /*用于处理异步操作,不能直接修改state 由action触发 也可触发action 只能是generator 函数 有两个参数 action ,effects 两个参数。第二个参数effect包括三个参数 (call,put,select) put 用于触发action ,call用于调用异步处理逻辑,select用于从state获取数据 */ effects:{ // 这个*代表的是它是一个异步函数,里面可以使用 yield 等待其他异步函数执行结果。 *GetShortnoteTemplateEffects({payload},{call,put}){ /*通过yield call()来调用数据接口方法和请求参数,yield表示同步调用,这个是generator提供的功能 call:与后台服务端接口进行交互。 第一个传参:后台服务器接口对应的名称。第二个参数:入参。*/ let res = yield call(GetShortnoteTemplate,payload.data); /*put用于触发actions action是一个单纯的包含{type,payload}的对象,type 是一个常量用来标示动作类型,payload 是这个动作携带的数据。 action需要通过dispatch()方式来发送 */ yield put({ type:'shortnoteReducer', payload:res, }); }, *AddShortnoteTemplateEffects({payload},{call,put}){ let res = yield call(AddShortnoteTemplate,payload.data); // console.log('AddShortnoteTemplate',res) yield put ({ type:'shortnoteReducer', payload:res, }) } }, //reducers,类似于redux中的reducer,是一个纯函数用来处理同步函数,是唯一一个可以修改 state的地方,由action触发 //它有action和state两个参数 //一个reducer会接受两个参数分别是oldstate和action,返回一个新的state reducers:{ /*GetShortnoteTemplateEffects可以理解为一个方法名 payload:就是 action 里传递过来的数据。 num 是传过来的,名字随便起,不是state中的num,这接收一个action*/ shortnoteReducer(state,{payload}){ // 当返回的状态为200时候,说明是调用成功的,可以继续执行。 if(payload.status === 200){ // return返回的是新的state,等于舍弃了旧的 state,重新 return 一个新的 state 作为当前 Model 的 state。 return{ // 一般情况下,我们要解开旧的 state,将它重新赋值给新的 state。...state 为 ES6 语法。 ...state, shortnote_data:payload.data.data, }; } }, } } export default shortnote;
上述处理完成后我们就可以在其他页面调用了。当然这个useEffect是写在函数里面的。
import { connect } from 'dva'; //比如说每次数据初始化的时候,可以这样写 useEffect(() => { props.dispatch({ //namespace+需要调用的reducer方法 type: 'shortnoteTemplate/GetShortnoteTemplateEffects', payload: { data: '', }, }); }, []);
在函数导出的时候还是需要做些额外的处理
/* connect的作用是将组件component和models结合在一起。 将models中的state绑定到组件的props中,并提供一些额外的功能。 譬如dispatch方法,dispatching function 是一个用于触发 action 的函数, action 是改变 State 的唯一途径,但是它只描述了一个行为,而 dipatch 可以看作是触发这个行为的方式 */ export default connect(({ shortnoteTemplate, loading }) => ({ loading: loading.effects['shortnoteTemplate/GetShortnoteTemplateEffects'], shortnote_data: shortnoteTemplate.shortnote_data, }))(shortnoteTemplateConfig);