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)
  );
};



复制代码

转载于:https://juejin.im/post/5d57de3ee51d4561cf15dfbf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值