您好,登錄后才能下訂單哦!
這篇文章主要介紹了react中間件的thunk和saga有什么區別,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
react中間件的thunk和saga區別:1、【redux-thunk】僅支持原始對象【(plain object)】,處理有副作用的action;2、【redux-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, 但是函數的內部可以多種多樣. 比如下面是一個獲取商品列表的異步操作所對應的 action
store 里面先引入中間件
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 的使用.
shopping-cart
例子很簡單, 展示的是如下過程:
商品列表 -->添加商品 -->購物車 -->付款
具體的頁面, 如下:
顯然, 這里有兩個明顯的異步操作需要執行:
獲取商品列表和付款
用 getAllProducts()
和 checkout()
來表示, 如果用 thunk, 那么這兩個異步的操作分屬于兩個不同的 action 中, 但是在 saga 中, 它們是集中處理的.
使用 saga, 我們先生成一個集中處理異步的 saga.JS 文件:
import { put, takeEvery, call } from 'redux-saga/effects' import { CHANGE_HITOKOTO_RESP, CHANGE_HITOKOTO } from '../actions/Hitokoto' import hitokotoApi from '../services/hitokoto' function gethitokoto() { return hitokotoApi.get().then(resp => resp) } export function* changeHitokoto() { const defaultHitokoto = { 'id': 234, 'hitokoto': '沒有誰能夠永遠堅強下去的, 每個人都會有疲累的無法站起的時候. 世間的故事, 就是為了這一刻而存在的哦.', 'type': 'a', 'from': '文學少女', 'creator': '醬七', 'created_at': '1468605914' }; 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) }
拋去其他部分 (具體用法我們待會解釋), 我們看到在 saga.JS 中集中了這兩個異步操作getAllProducts()
和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) 異步操作的流程是可以控制的, 可以隨時取消相應的異步操作.
缺點: 太復雜, 學習成本較高
感謝你能夠認真閱讀完這篇文章,希望小編分享react中間件的thunk和saga有什么區別內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。