Redux-saga 基础学习
参考:
https://juejin.im/post/58eb4100ac502e006c45d5c9
https://yanqiw.github.io/react/2017/03/05/redux-saga.html
http://www.cnblogs.com/libin-1/p/6858558.html
什么是Redux-saga
它是一个用于管理 Redux 应用异步操作的中间件,通过创建 Sagas 将所有的异步操作逻辑收集在一个地方集中处理,像一个分散的支线在你的应用中单独负责解决异步的action(类似于后台运行的进程),从而代替 redux-thunk 中间件。
逻辑存在两个地方:
l Reducers 负责处理 action 的 state 更新。
l Sagas 负责协调那些复杂或异步的操作。
重要概念
副作用:
在action触发reduser之后执行的一些动作,这些动作包括但不限于,连接网络,io读写,触发其他action。因为Sage的副作用是通过redux的action触发的,每一个action,sage都会像reduser一样接收到。并且通过触发不同的action, 我们可以控制这些副作用的状态,例如,启动,停止,取消。所以,我们可以理解为Sage是一个可以用来处理复杂的异步逻辑的模块,并且由redux的action触发。
redux-saga提供了几种产生副作用的方式:主要用到了有两种takeEvery和takeLates。
takeEvery:会在接到相应的action之后不断产生新的副作用。 比如,做一个计数器按钮,用户需要不断的点击按钮,对后台数据更新,这里可以使用takeEvery来触发。
takeLatest:在相同的action被触发多次的时候,之前的副作用如果没有执行完,会被取消掉,只有最后一次action触发的副作用可以执行完。
Reduex能做:
l 调用一个异步函数;
l 发起一个 action 到 Store;
l 启动一个后台任务或者等待一个满足某些条件的未来的 action。
Effects
是一个 javascript 对象,里面包含描述异步动作的信息,可以通过 yield 传达给 sagaMiddleware 执行。
在 redux-saga 世界里,所有的 Effect 都必须被 yield 才会执行
常用API
call
用来调用异步函数,将异步函数和函数参数作为call函数的参数传入,返回一个js对象。saga引入他的主要作用是方便测试,同时也能让我们的代码更加规范化。
call操作是阻塞的,只有等promise回来后才能继续执行
fork
当调用fork启动一个任务时,该任务在后台继续执行,从而使得我们的执行流能继续往下执行而不必一定要等待返回。
put
作用和 redux 中的 dispatch 相同。
yield put({ type: 'CLICK_BTN' });
select
作用和 redux thunk 中的 getState 相同。
const id = yield select(state =>state.id);
调用put方法后,saga内部会分发action通知Store更新state。
take
等待 redux dispatch 匹配某个(由用户决定) pattern 的 action 。在执行顺序执行到take语句时才会相应action。
在genetator中使用take语句等待action时,generator被阻塞,等待action被分发,然后继续往下执行。
先等待一个按钮点击的 action ,然后执行按钮点击的 saga:
while (true) {
yield take('CLICK_BUTTON');
yield fork(clickButtonSaga);
}
阻塞调用和无阻塞调用
redux-saga 可以用 fork 和 call 来调用子 saga ,其中 fork 是无阻塞型调用,call 是阻塞型调用。
使用例子:
在用户提交表单的时候,我们想要做如下事情:
l 校验一些输入信息 (简单, 写在组件里)
l 弹起提示信息(写一个公用的提示信息模块,这样别的页面引入就可以用了)
l 提交后端服务 (直接组件里面fetch)
l 拿到后端返回状态 (promise实现)
l 隐藏提示信息 (给组建加一个控制属性)
l 更新redux store(dispatch咯。。。)
但是一旦涉及到多个表单提交,代码就会很长,重复代码很多。
用了redux-saga之后:
form组件触发提交action (一行简单的dispatch)
reducer这个action不需要自己处理
saga提交表单的副作用开始执行 (监听到触发副作用的action)
l 校验一下
l 通知显示层弹起信息框 (dispatch一下变更控制信息框弹起的store)
l 提交表单 (yield一个promis,yield是javascriptgenerator的语法,稍后有介绍)
l 拿到后端返回状态
l 更新redux store(dispatch一下)
使用了Saga后,react只负责数据如何展示,redux来负责数据的状态和绑定数据到react,而Saga处理了大部分复杂的业务逻辑。