在Redux中常要管理异步操作,目前社区流行的有Redux-Saga、Redux-thunk等。在管理复杂应用时,推荐使用Redux-Saga,它提供了用 generator 书写类同步代码的能力。

在讲解 ReduxSaga 前,先要说明一下 Redux Middleware 的概念。

Middleware

它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。

如果写过 Koa 或者 Express ,就会很容易理解 Middleware 的概念。

可以说,Middleware 是一种置于一个调用发起到被处理这段过程之间的函数。它可以对发起的调用进行处理,处理后直接返回,或者调用下一个中间件。

在Redux中,使用柯里化函数声明中间件,一个简单的例子如下:

/**
* 记录所有被发起的 action 以及产生的新的 state。
*/
const logger = store => next => action => {
console.group(action.type)
console.info('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
console.groupEnd(action.type)
return result
}

然后需要将它应用到Redux上

import { createStore, combineReducers, applyMiddleware } from 'redux'

const todoApp = combineReducers(reducers)
const store = createStore(
todoApp,
// applyMiddleware() 告诉 createStore() 如何处理中间件
applyMiddleware(logger, crashReporter)
)

之后dispatch的每一个action都会触发log中间件。

更详细的用法在Redux文档里说明得很详细了,Redux-Middleware

使用Redux Saga

先定一个小目标,写一个异步增加的demo。

先来创建一个sagas.js文件,用来存放我们的sagas。

import { delay } from 'redux-saga'
import { put, takeEvery } from 'redux-saga/effects' export function* plusAsync() {
yield delay(1000)
yield put({ type: 'PLUS' })
} // 在dispatch到store并且匹配pattern的每一个action上派生一个saga
export function* watchPlusAsync() {
yield takeEvery('PLUS_ASYNC', incrementAsync)
}

在上篇例子的基础上,增加一个按钮,用来派发PLUS_ASYNC事件。

 <button onClick={dispatch({type: 'PLUS_ASYNC'}}>{"plusAsync"}</button>

在使用时,经常需要将多个sagas合并成一个。

import { all } from 'redux-saga/effects'

// ...

export default function* rootSaga() {
yield all([
watchPlusAsync()
])
}

最后,需要创建saga Middleware。并将中间件应用到redux上。

import { createStore, applyMiddleware } from "redux";

// ...

// 创建一个Store
const sagaMiddleware = createSagaMiddleware()
const store = createStore(
counter,
applyMiddleware(sagaMiddleware)
) // 运行sagas
sagaMiddleware.run(allSagas);

常用API说明

middleware.run(saga, ...args)

动态地运行 saga。只能 用于在 applyMiddleware 阶段 之后 执行 Saga。

takeEvery(pattern, saga, ...args)

在发起(dispatch)到 Store 并且匹配 pattern 的每一个 action 上派生一个 saga。

pattern用来匹配对应的TYPE,对应到指定的saga处理函数上。

args就是相当于指定给saga的参数数组,并且takeEvery会将action拼到最后一个参数上。

takeLatest(pattern, saga, ...args)

在发起到 Store 并且匹配 pattern 的每一个 action 上派生一个 saga。并自动取消之前所有已经启动但仍在执行中的 saga 任务。

这个函数可以说是takeEvery的防抖版本。

具体例子可以查看这里-redux_saga_example

put(action)

创建一个 Effect 描述信息,用来命令 middleware 向 Store 发起一个 action。 这个 effect 是非阻塞型的,并且所有向下游抛出的错误(例如在 reducer 中),都不会冒泡回到 saga 当中。

all

创建一个 Effect 描述信息,用来命令 middleware 并行地运行多个 Effect,并等待它们全部完成。这是与标准的 Promise#all 相当对应的 API。

更多API请查看Saga文档

总结

saga的用法比较简单,分为4步。

  1. 创建saga并且将使用takeEvery给每一个符合patternaction都增加一个对应的saga处理函数。
  2. 使用all导出编写的saga。
  3. 创建saga中间件,在使用redux创建store时,应用saga中间件。
  4. 运行中间件。

感谢阅读。

react系列(六)Redux Saga的更多相关文章

  1. [React] 14 - Redux: Redux Saga

    Ref: Build Real App with React #14: Redux Saga Ref: 聊一聊 redux 异步流之 redux-saga  [入门] Ref: 从redux-thun ...

  2. react native redux saga增加日志功能

    redux-logger地址:https://github.com/evgenyrodionov/redux-logger 目前Reac native项目中已经使用redux功能,异步中间件使用red ...

  3. react系列(五)在React中使用Redux

    上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ...

  4. react系列(四)Redux基本概念和使用

    Redux基本概念和使用 先从Flux开始 先放一个Flux官网的链接.需要fq. Flux是Facebook提出的一种构建客户端网页应用的应用架构,它是一种抽象程度很高的设计模式,鼓励单向数据流. ...

  5. react系列教程

    这个系列将从基础语法讲起,把react全家桶都讲到,然后到具体的使用,最后完成后,会写一个完整的demo. 前置要求: 基本的CSS,JS要熟练. 部分ES6语法需要了解.可以参考下面提到的阮一峰老师 ...

  6. 在React中使用Redux

    这是Webpack+React系列配置过程记录的第六篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...

  7. React 系列教程 1:实现 Animate.css 官网效果

    前言 这是 React 系列教程的第一篇,我们将用 React 实现 Animate.css 官网的效果.对于 Animate.css 官网效果是一个非常简单的例子,原代码使用 jQuery 编写,就 ...

  8. CSS 魔法系列:纯 CSS 绘制各种图形《系列六》

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  9. WCF编程系列(六)以编程方式配置终结点

    WCF编程系列(六)以编程方式配置终结点   示例一中我们的宿主程序非常简单:只是简单的实例化了一个ServiceHost对象,然后调用open方法来启动服务.而关于终结点的配置我们都是通过配置文件来 ...

随机推荐

  1. PAT 1028. List Sorting

    #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> ...

  2. Hibernate Annotation (Hibernate 注解)

    简介: 传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载. 然而现在借助新的 Hibernate   Annotation 库, ...

  3. php浮点数加减乘除bug

    项目测试阶段,少部分微信支付成功,但是在异步通知校对订单金额是否一致时,一直被认定订单金额不一致. 类似于: 浏览器输出: 分析: 因为计算机二进制无法准确表示部分浮点数(如2.03.0.58等等), ...

  4. Nodejs学习笔记之复制文件

    前端童鞋都知道,javascript是没有权限操作磁盘文件的,server童鞋一向都很鄙视.但是nodejs可谓让咱们前端扬眉吐气啊,最近在学node,其强大的功能让人异常激动和兴奋.今天就学习了它怎 ...

  5. pv-date-handle

    pv-date-handle 这是一个时间格式化转换的小工具,简单易用 ## 快速开始 安装`npm install pv-date-handle -S` ```js import formateDa ...

  6. 26_线程池_ThreadPoolExecutor

    [ThreadPoolExecutor简述] 无论是Executors类的newFixedThreadPool().newSingleThreadExecutor(),还是newCachedThrea ...

  7. 【统计学】英文概念之Mean和Average的区别

    通过专门检索和其他课本的比较,得到了如下结论.统计学在分析数据时,需要对数据进行最基础的描述性分析.在众多描述分析的指标中,平均数指标能够反映分布数列集中趋势.但是平均数指标包括两类:一类是数值平均数 ...

  8. 如何在 Azure 中的 Linux 经典虚拟机上设置终结点

    在 Azure 中使用经典部署模型创建的所有 Linux 虚拟机都可以通过专用网络通道与同一云服务或虚拟网络中的其他虚拟机自动通信. 但是,Internet 或其他虚拟网络中的计算机需要终结点将入站网 ...

  9. JavaWeb笔记——MVC设计模式和JavaWeb经典三层架

    1 MVC设计模式 MVC设计模式 MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(C ...

  10. 五、mariadb遇到的坑——Linux学习笔记

    C#连接MySQL异常:The host localhost does not support SSL connections. 解决方案: 连接字符串添加如下语句. SslMode = none; ...