Redux-Saga
概念
Redux-saga是一个用于管理应用程序副作用的库。
副作用 Side Effects 是指 异步获取数据,读取浏览器缓存等操作。
目的:是为了让副作用管理更容易,执行更高效。
特点
redux-saga是redux的一个中间件,意味着这个线程可以通过正常的redux-action从主应用程序启动,暂停和取消。
并且能访问完整的redux state,也可以dispatch redux action。
这意味着应用的逻辑会出现在两个地方:
- reducer 负责处理action的state更新
- Sagas 负责协调 那些复杂的操作或者异步的操作。
在redux-saga中,所有的任务都通过yield effects来完成,Effects都是简单的JavaScript对象,包含了要被Saga Middleware执行的信息。
与redux-thunk的区别
thunks会在action被创建时调用,而sagas会在应用启动时调用,并且监听派发给store的action,然后决定基于这个action来做什么,或者发起一个异步调用,或者发起其他的action到state中,甚至是调用其他的sagas。
安装
yarn add redux-saga
创建
// store/index.js // 创建store的位置
import { createStore, applyMiddleware } from 'redux'
import { createSagaMiddleware } from 'redux-saga'
import reducer from './reducer'
// 导入 定义好的 mySaga.js 文件
import mySaga from './mySaga'
// 1. 创建saga中间件
const sagaMiddleware = createSagaMiddleware()
// 创建store
const store = createMiddleware(
reducer,// reducer作为第一个参数
applyMiddleware(sagaMiddleware) // 通过applyMiddleware方法 使用中间件
)
// 运行中间件
sagaMiddleware(mySaga).run()
export default store
使用
自定义的 saga文件。
saga 必须导出为 一个Generator函数
// 导入辅助函数
import { takeEvery } from 'redux-saga'
// 导入 Effect Creator
import { call, put } from 'redux-saga/effects'
import axios from 'axios'
function* getInitList(){
const res = yield axios.get('https://api.github.com/users/forsakensoul35/repos')
const action = {
type:'init_list_item',
data:res
}
yield put(action)
}
function* mySaga(){
// 要监听的action
// 监听事件的类型 为 GET_INIT_LIST
// 就执行 getInitList函数
yield takeEvery(GET_INIT_LIST,getInitList)
// 在这里面,可以监听各种类型的action
}
// 导出 监听器 mySaga
export default mySaga
核心Api
辅助函数
takeEvery
监听每一个指定的action,监听到一次,就执行一次。允许多次同时启动。
takeLatest
与takeEvery不同,在任意时刻,takeLatest只允许一个特定的任务执行,并且这个任务是最后启动的那次,如果之前已经有一个任务在执行,那之前的这个任务会自动被取消。
Effect Creator
put (action)
put函数 是用来发送 action的effect,可以理解为redux中的dispatch方法,当put一个action之后,reducer会根据action的type做对应的操作。
call(fn,...args)
call函数可以理解为 可以调用其他函数的函数,命令middleware执行fn函数,args为函数的参数。
fn也可以是一个Generator函数,也可以是一个返回Promise对象的普通函数。
fork(fn,...args)
fork函数和call函数很想,都是用来调用其他函数的,但是fork函数是非阻塞函数,也就是说函数执行完fork这一行代码之后,会立即执行下一行代码,不会 等待fn函数的返回结果。
select(selector,...args)
select函数是用来指示middleware调用可提供的选择器获取store上的state数据,可以理解为redux框架上的store.getState方法