聊聊 effects 與 reducers--React AntDesign Dva

原文: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:


image.png

      <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視圖文件了,如下:













image.png

      <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 ,它會在控制檯打印出什麼呢?


image.png

      <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 還是比較簡單的。大家理解了嗎?

發佈了62 篇原創文章 · 獲贊 10 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章