react中間件的thunk和saga區別:1、【redux-thunk】僅支援原始物件【(plain object)】,處理有副作用的action;2、【redux-saga】中處理了所有的非同步操作, 非同步介面部分一目了然。
本教學操作環境:windows7系統、React17版,此方法適用於所有品牌電腦。
相關學習推薦:react影片教學
#react中間件的thunk和saga區別:
react中間件的thunk和saga區別:
1、redux-thunk 的使用與缺點
(1)redux-thunk 的使用thunk 是redux 作者給出的中間件, 實作極為簡單, 10 多行程式碼:function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;這幾行程式碼做的事情也很簡單, 判別action 的型別, 如果action 是函數, 就呼叫這個函數, 呼叫的步驟為:
action(dispatch, getState, extraArgument);#發現實參為dispatch 和getState, 因此我們在定義action 為thunk 函數是, 一般形參為dispatch 和getState.(2)redux-thunk 的缺點#thunk 的缺點也是很明顯的, thunk 僅僅做了執行這個函數, 並不在乎函數主體是什麼, 也就是說thunk 使得redux 可以接受函數作為action, 但是函數的內部可以多種多樣. 比如下面是一個獲取商品列表的異步操作所對應的actionstore 裡面先引入中間件
import { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from './reducers/index'; const initialState = {}; const middleware = [thunk]; export const store = createStore( rootReducer, initialState, compose( applyMiddleware(...middleware), Windows.__REDUX_DEVTOOLS_EXTENSION__ && Windows.__REDUX_DEVTOOLS_EXTENSION__() ) );action 檔案裡
import { FETCH_POSTS, NEW_POST } from './type' export const fetchPosts = () => dispatch => { fetch("https://jsonplaceholder.typicode.com/posts") .then(res => res.JSON()) .then(posts => dispatch({ type: FETCH_POSTS, payload: posts }) ) } export const createPost = postData => dispatch => { fetch("https://jsonplaceholder.typicode.com/posts",{ method: "POST", headers:{ "content-type":"application/json" }, body:JSON.stringify(postData) }) .then(res => res.JSON()) .then(post => dispatch({ type: NEW_POST, payload: post }) ) }從這個具有副作用的action 中, 我們可以看出, 函數內部極為複雜.如果需要為每一個非同步操作都如此定義一個action, 顯然action 不易維護.action 不易維護的原因:
I)action 的形式不統一##II )就是非同步操作太為分散, 分散在了各個action 中
2、redux-saga 的使用
在redux-saga 中, action 是plain object(原始物件), 並且集中處理了所有的非同步操作, 下面我們以redux-saga 的官方例子shopping-cart
為例, 來說說redux-saga 的使用.
範例很簡單, 展示的是以下過程:
商品列表-->新增商品-->購物車-->付款
具體的頁面, 如下:
顯然, 這裡有兩個明顯的非同步操作需要執行:#取得商品清單和付款
用
和
checkout()來表示, 如果用thunk, 那麼這兩個非同步的操作分屬於兩個不同的action 中, 但是在saga 中, 它們是集中處理的.使用saga, 我們先生成一個集中處理異步的saga.JS 文件:
<pre class="brush:php;toolbar:false">import { put, takeEvery, call } from &#39;redux-saga/effects&#39;
import { CHANGE_HITOKOTO_RESP, CHANGE_HITOKOTO } from &#39;../actions/Hitokoto&#39;
import hitokotoApi from &#39;../services/hitokoto&#39;
function gethitokoto() {
return hitokotoApi.get().then(resp => resp)
}
export function* changeHitokoto() {
const defaultHitokoto = {
&#39;id&#39;: 234,
&#39;hitokoto&#39;: &#39;没有谁能够永远坚强下去的, 每个人都会有疲累的无法站起的时候. 世间的故事, 就是为了这一刻而存在的哦.&#39;,
&#39;type&#39;: &#39;a&#39;,
&#39;from&#39;: &#39;文学少女&#39;,
&#39;creator&#39;: &#39;酱七&#39;,
&#39;created_at&#39;: &#39;1468605914&#39;
};
try {
const data = yield call(gethitokoto);
const hitokotoData = JSON.parse(data);
yield put({ type: CHANGE_HITOKOTO_RESP, hitokotoData });
} catch (error) {
yield put({ type: CHANGE_HITOKOTO_RESP, hitokotoData: defaultHitokoto });
}
}
export default function* shici() {
yield takeEvery(CHANGE_HITOKOTO, changeHitokoto)
}</pre>
拋去其他部分(具體用法我們待會解釋), 我們看到在saga.JS 中集中了這兩個非同步操作
和
checkout()此外, 在saga 中的action 跟原始物件是完全相同的, 我們來看saga 中的action creator :
export const GET_ALL_PRODUCTS = 'GET_ALL_PRODUCTS' export function getAllProducts() { return { type: GET_ALL_PRODUCTS, } }
上述的action creator 中, 創建的action 是一個plain object, 跟我們在redux 中同步action 的樣式是統一的.
redux-saga 的優缺點
優點:
(1)集中處理了所有的非同步運算, 非同步介面部分一目了然
(2)action 是普通物件, 這跟redux 同步的action 一模一樣
(3)透過Effect, 方便非同步介面的測試
(4)透過worker 和watcher 可以實現非阻塞非同步呼叫, 並且同時可以實現非阻塞呼叫下的事件監聽
#(5) 非同步操作的流程是可以控制的, 可以隨時取消對應的非同步操作.javascript學習教學############# 缺點: 太複雜, 學習成本較高相關學習推薦:
以上是react中間件的thunk和saga差別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!