聊聊 effects 与 reducers--React AntDesign Dva

那年仲夏 提交于 2020-01-15 07:34:05

原文:https://www.yuque.com/yuxuanbeishui/zog1rm/tgmgws

今天我们就来聊聊 dva 中的 effects 与 reducers以及其中涉及的关键字的使用。如果它们之间工作流程还不太熟悉,请阅读:分析models源码


为了让小伙伴们更好的理解与使用 effects 与 reducers,我们依然找现有的 models 为例:


位置:"/src/pages/Profile/models/profile.js"


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-1"></span><span class="lake-preview-codeblock-content"><span class="cm-keyword">import</span> { <span class="cm-def">queryBasicProfile</span>, <span class="cm-def">queryAdvancedProfile</span> } <span class="cm-keyword">from</span> <span class="cm-string">'@/services/api'</span>;


export default {
namespace: ‘profile’,

state: {
basicGoods: [],
advancedOperation1: [],
advancedOperation2: [],
advancedOperation3: [],
},

effects: {
fetchBasic({ payload }, { call, put }) {
const response = yield call(queryBasicProfile, payload);
yield put({
type: ‘show’,
payload: response,
});
},
fetchAdvanced(_, { call, put }) {
const response = yield call(queryAdvancedProfile);
yield put({
type: ‘show’,
payload: response,
});
},
},

reducers: {
show(state, { payload }) {
return {
state,
payload,
};
},
},
};


一、effects 内函数有什么特点?


1、分析 effects 函数形参


从外观上看,我们发现每个自定义函数前都有 " * " 修饰 ,函数有两个参数。


有小伙伴反映说,对( { payload } , { call, put })函数参数不太理解,这是固定写法吗?里面还有其他关键字吗?


那好,我们就一起在控制台上打印出这两个参数:(action,effects)


我先将上述的 fetchBasic 函数代码修改如下:


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-1"></span><span class="lake-preview-codeblock-content"><span class="cm-meta">...</span>


*fetchBasic( action, effects ) {

console.log( ‘action’, action );
console.log( ‘paramsTwo’, effects );
const { payload } = action;
const { call, put } = effects;

const response = yield call( queryBasicProfile, payload );
yield put( {
type: ‘show’,
payload: response,
} );
},


如果有不懂此写法的小伙伴: const { payload } = action ,请阅读:解析赋值


在控制台上我可以观察到:


第一个参数 action:


      <span data-role="maximize" class="lake-image-editor-maximize" style="display: none;"><span class="lake-icon lake-icon-full-screen"></span></span>
      
    </span>
  </span>
</span>


这里我们可以拿到两个常用的关键字值:payload , type 


既然第一个参数 action ,它也叫形参。那在哪个位置调用 fetchBasic 函数的呢?


这个时候我们就要去找 相对应的UI视图文件了,如下:













      <span data-role="maximize" class="lake-image-editor-maximize" style="display: none;"><span class="lake-icon lake-icon-full-screen"></span></span>
      
    </span>
  </span>
</span>


这个时候,我们就明白了,原来我们可以在 UI视图文件里调用 effects 中的函数,而且函数的第一个形参就是我们手动传入相关必要参数。


比如,我们要编写登陆功能代码,可以传入 “用户名”、“密码”:


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-0"></span><span class="lake-preview-codeblock-content"><span class="cm-meta">...</span>


dispatch({
type:‘user/login’,
payload:{ username:‘羽旋杯水’, password:‘123456’},
});


这个时候,我们就在 user.js 文件的 *login( { payload },{ call , put} ), 此时 payload = { username:'羽旋杯水', password:'123456'} ,将拿到的数据经过逻辑处理,就可以和后端进行交互了。


OK ,我现在来看第二个参数 effects ,它会在控制台打印出什么呢?


      <span data-role="maximize" class="lake-image-editor-maximize" style="display: none;"><span class="lake-icon lake-icon-full-screen"></span></span>
      
    </span>
  </span>
</span>


从打印结果看,dva 预设的默认函数还是比较多的,但是我们比较常用 3 个,分别是:call ,put ,select


2、call、put、select 用法


那它们都代表什么含义?怎么使用呢?


call:用于调用异步逻辑,支持 promise 。


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-0"></span><span class="lake-preview-codeblock-content"><span class="cm-comment">//call用法:</span>

//request :代表发送ajax请求
//payload :代表发送ajax请求时,所需要的参数

const res = yield call(request,payload);


put:用于触发 action。


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-0"></span><span class="lake-preview-codeblock-content"><span class="cm-comment">//put用法:</span>

//xx代表:models名
//jj代表:函数名
//res代表:所需的数据

yield put ({
type:‘xx/jj’,
payload:res
});


select:用于从 state 里获取数据。


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-0"></span><span class="lake-preview-codeblock-content"><span class="cm-comment">//select用法:</span>

//data代表:所需要的数据
//其中state:代表所有models数据

const data = yield select(state=>state.data);


细心的小伙伴就有疑问了,每个关键字前面都有 yield ,yield的作用是什么呢?


yield作用:保证当前语句执行完毕后,再执行下面的代码。


二、reducers 内函数有什么特点?


1、分析 reducers 函数形参


<div class="lake-codeblock-content"><div class="CodeMirror"><pre class="cm-s-default"><span class="lake-preview-line"><span class="lake-preview-line-number lake-lm-pad-level-1"></span><span class="lake-preview-codeblock-content"><span class="cm-meta">...</span>


reducers: {
show(state, { payload }) {
return {
state,
payload,
};
},
},


大多数情况下,我们只需要一个 show 函数就可以完成大部分业务需求了。


show 函数的第一个形参 state,就是我们的预设数据。

show 函数的第二个形参 action,就是我们传过来的参数数据。


有些小伙伴不太理解其中 return 返回内容,我们就来分析一下吧。


分析之前,推荐阅读:属性展开


这里的 return { ...state, ...payload },意思是将 payload 传过来的数据,保存到预设 state 里。所以当 state 数据发生改变后,页面也会随之重新渲染。


其实,effects 和 reducers 还是比较简单的。大家理解了吗?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!