0

0

react中间件的thunk和saga区别是什么

coldplay.xixi

coldplay.xixi

发布时间:2020-12-17 11:32:16

|

3847人浏览过

|

来源于php中文网

原创

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

react中间件的thunk和saga区别是什么

本教程操作环境:windows7系统、React17版,该方法适用于所有品牌电脑。

相关学习推荐:react视频教程

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例子很简单, 展示的是如下过程:

Dreamlike.art
Dreamlike.art

内置5种模型的AI图像生成器

下载

商品列表 -->添加商品 -->购物车 -->付款

具体的页面, 如下:

显然, 这里有两个明显的异步操作需要执行:

获取商品列表和付款

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) 异步操作的流程是可以控制的, 可以随时取消相应的异步操作.

缺点: 太复杂, 学习成本较高

相关学习推荐:javascript学习教程

相关专题

更多
苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

115

2025.12.24

拼豆图纸在线生成器
拼豆图纸在线生成器

拼豆图纸生成器有PixelBeads在线版、BeadGen和“豆图快转”;推荐通过pixelbeads.online或搜索“beadgen free online”直达官网,避开需注册的诱导页面。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

82

2025.12.24

俄罗斯搜索引擎yandex官方入口地址(最新版)
俄罗斯搜索引擎yandex官方入口地址(最新版)

Yandex官方入口网址是https://yandex.com。用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

546

2025.12.24

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

150

2025.12.24

php框架基础知识汇总
php框架基础知识汇总

php框架是构建web应用程序的架构,提供工具和功能,以简化开发过程。选择合适的框架取决于项目需求和技能水平。实战案例展示了使用laravel构建博客的步骤,包括安装、创建模型、定义路由、编写控制器和呈现视图。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

20

2025.12.24

Word 字间距调整方法汇总
Word 字间距调整方法汇总

本专题整合了Word字间距调整方法,阅读下面的文章了解更详细操作。

47

2025.12.24

任务管理器教程
任务管理器教程

本专题整合了任务管理器相关教程,阅读下面的文章了解更多详细操作。

7

2025.12.24

AppleID格式
AppleID格式

本专题整合了AppleID相关内容,阅读专题下面的文章了解更多详细教程。

12

2025.12.24

csgo视频观看入口合集
csgo视频观看入口合集

本专题整合了csgo观看入口合集,阅读下面的文章了知道更多入口地址。

371

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 2.9万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

React核心原理新老生命周期精讲
React核心原理新老生命周期精讲

共12课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号