本文摘自PHP中文网,作者coldplay.xixi,侵删。
react中间件的thunk和saga区别:1、【redux-thunk】仅支持原始对象【(plain object)】,处理有副作用的action;2、【redux-saga】中处理了所有的异步操作, 异步接口部分一目了然。

本教程操作环境:windows7系统、React17版,该方法适用于所有品牌电脑。
相关学习推荐:react视频教程
react中间件的thunk和saga区别:
1、redux-thunk 的使用与缺点
(1)redux-thunk 的使用
thunk 是 redux 作者给出的中间件, 实现极为简单, 10 多行代码:
1 2 3 4 5 6 7 8 9 10 11 | 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 是函数, 就调用这个函数, 调用的步骤为:
1 | action(dispatch, getState, extraArgument);
|
发现实参为 dispatch 和 getState, 因此我们在定义 action 为 thunk 函数是, 一般形参为 dispatch 和 getState.
(2)redux-thunk 的缺点
thunk 的缺点也是很明显的, thunk 仅仅做了执行这个函数, 并不在乎函数主体内是什么, 也就是说 thunk 使得 redux 可以接受函数作为 action, 但是函数的内部可以多种多样. 比如下面是一个获取商品列表的异步操作所对应的 action
store 里面先引入中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 文件里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 :
1 2 3 4 5 6 | 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区别是什么的详细内容,更多文章请关注木庄网络博客!
相关阅读 >>
React中的refs是什么
zepto与React区别是什么
vue和React监听数据的区别是什么?
开发React用什么工具?
React中什么是hoc
React中页面如何传值
React向数组中追加数据的方法
React中如何防范xss攻击?(代码示例)
React中同级组件如何传值
React怎么循环map
更多相关阅读请进入《React》频道 >>
人民邮电出版社
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者
转载请注明出处:木庄网络博客 » react中间件的thunk和saga区别是什么