redux-thunk|redux-thunk vs redux-saga的状态管理

状态管理 写这篇笔记更正之前理解的误区,背景呢,一次需求中实现根据参数 itemId 等分页信息拉取接口至少5次, 并在state 中并保存合并对应itemId下的数据, 这里有两个步骤1,每次请求的数据在赋值给state之前 ,要获取到原有state中的值; 2,合并操作。那如何在reduce 中获取到原有state的值呢, 就是状态管理了.
redux redux 本身非常简单,它只有三个核心概念:state、action 和 reducer, 直接看官网就可以了, 或者网上成堆的10 分钟理解 Redux。 将需要修改的 state 都存入到 store 里, 发起一个 action 用来描述发生了什么,用 reducers 描述 action 如何改变 state tree 。因此只有 reducer 能修改 state。redux 通过这些约束,让数据的变化变得可预测、可回溯。在创建 store 的时候需要传入 reducer,真正能改变 store 中数据的是 store.dispatch API。可以采用两种中间件redux-thunk 和redux-saga。 当然也可以直接使用ant design pro是基于UmiJS、dva,而 dva 也是基于 redux、redux-saga 和 react-router 的进一步封装。
redux-thunk redux-thunk 中间件可以允许你写的 action creator 函数可以返回 action 对象的同时,也可以返回一个函数。函数传递两个参数 (dispatch,getState), 在函数体内进行业务逻辑的封装, getState() 方法获取 state这个中间件可以被用来延缓分发 action 的时机,或者实现只在满足某个条件的时候才触发 action。简而言之,中间件都是对 store.dispatch () 的增强。以下是官网的一个例子

import { applyMiddleware, createStore } from 'redux'; import thunk from 'redux-thunk'; const store = createStore( reducers, applyMiddleware(thunk) ); // 而且可以使用 Promise 来控制数据流。function makeSandwichesForEverybody() { return function (dispatch, getState) { if (!getState().sandwiches.isShopOpen) {// 返回 Promise 并不是必须的,但这是一个很好的约定, // 为了让调用者能够在异步的 dispatch 结果上直接调用 .then() 方法。return Promise.resolve() }// 可以 dispatch 普通 action 对象和其它 thunk, // 这样我们就可以在一个数据流中组合多个异步 action。return dispatch( makeASandwichWithSecretSauce('My Grandma') ).then(() => Promise.all([ dispatch(makeASandwichWithSecretSauce('Me')), dispatch(makeASandwichWithSecretSauce('My wife')) ]) ).then(() => dispatch(makeASandwichWithSecretSauce('Our kids')) ).then(() => dispatch(getState().myMoney > 42 ? withdrawMoney(42) : apologize('Me', 'The Sandwich Shop') ) ) } }复制代码

以上就是异步 Action ,thunk 是判别 action 的类型,如果 action 是函数,就调用这个函数,但是函数的内部可以多种多样。比如下面是一个获取matching 中图片下面的信息的异步操作所对应的 action,然而需要为每一个异步操作都如此定义一个 action,显然 会有大量的action, 并且action 不易维护, 这是action 的副作用,也正是thunk 的缺点仅仅调用的函数。
redux-saga 官网上的描述redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高效,测试更简单。 粗浅的使用后的感受是很强大-各种情况下的流程控制都有对应的api,这些api保证了更简便的流程控制和易于测试的好处,因 thunk 插件还是需要你自己来写promise来保证各种异步和异常。那redux-saga 中间件中如何获取state呢,更简单select(selector, ...args)
const keyList = yield select(state => {}); 复制代码

几种常用的用法 Sagas 被实现为 Generator functions,一旦 Promise 被 resolve,middleware 会恢复 Saga 接着执行,直到遇到下一个 yield。 点击获取以下详细的demo例子
  • put 用于创建 dispatch Effect。
  • takeEvery(pattern, saga, ...args)在发起(dispatch)到 Store 并且匹配 pattern 的每一个 action 上派生一个 saga。
  • call 用于创建 Effect。发起异步或者同步操作
  • select 用于创建一个 Effect, 返回当前 Store state 上的一部分数据
  • fork 创建一个 Effect,用来命令 middleware 以 非阻塞调用 的形式执行 fn
  • cacel 创建一个 Effect,用来命令 middleware 取消之前的一个分叉任务-之前 fork 指令返回的 Task 对象
import { createStore, applyMiddleware } from 'redux' import createSagaMiddleware from 'redux-saga'//... import { demoSaga } from './demoSagas'const store = createStore( reducer, applyMiddleware(createSagaMiddleware(demoSaga)) )import { delay } from 'redux-saga' import { put, takeEvery } from 'redux-saga/effects'// demoSagas.js // Our worker Saga: 将执行异步的 获取用户信息 export function* getUser() { const user = yield call(fetch, { // method: "POST" resource: '' }); }// Our watcher Saga: const watchGet= function* watchGet() { yield takeEvery(getUserRequested, getUser); }cnost getActions = { [getUserRequested]: state => { return { ...state, isLogging: true }; }, [getUserSucceed]: (state, { payload: { avatar, name, email } }) => { return { ...state, isLogging: false, user: { avatar, name, email } }; }, [getUserFailed]: state => { return { ...state, isLogging: false }; } }; // rootSaga.js export default function* rootSaga() { import { all, call } from 'redux-saga/effects'; import { watchAppSagas } from './reducers/demoReducer'; export const sagas = function* rootSaga() { yield all( [ ...watchAppSagas, ].map(call) ); }; 复制代码

【redux-thunk|redux-thunk vs redux-saga的状态管理】转载于:https://juejin.im/post/5d57de3ee51d4561cf15dfbf

    推荐阅读