写这篇笔记更正以前理解的误区,背景呢,一次需求中实现根据参数 itemId 等分页信息拉取接口至少5次, 并在state 中并保存合并对应itemId下的数据, 这里有两个步骤1,每次请求的数据在赋值给state以前 ,要获取到原有state中的值; 2,合并操做。那如何在reduce 中获取到原有state的值呢, 就是状态管理了.react
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 的进一步封装。git
redux-thunk 中间件能够容许你写的 action creator 函数能够返回 action 对象的同时,也能够返回一个函数。函数传递两个参数 (dispatch,getState), 在函数体内进行业务逻辑的封装, getState() 方法获取 state
这个中间件能够被用来延缓分发 action 的时机,或者实现只在知足某个条件的时候才触发 action。简而言之,中间件都是对 store.dispatch () 的加强。如下是官网的一个例子github
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
官网上的描述redux-saga 是一个用于管理应用程序 Side Effect(反作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让反作用管理更容易,执行更高效,测试更简单
。 粗浅的使用后的感觉是很强大-各类状况下的流程控制都有对应的api,这些api保证了更简便的流程控制和易于测试的好处,因 thunk 插件仍是须要你本身来写promise来保证各类异步和异常。那redux-saga 中间件中如何获取state呢,更简单select(selector, ...args)
api
const keyList = yield select(state => {});
复制代码
Sagas 被实现为 Generator functions,一旦 Promise 被 resolve,middleware 会恢复 Saga 接着执行,直到遇到下一个 yield。 点击获取如下详细的demo例子promise
takeEvery(pattern, saga, ...args)
在发起(dispatch)到 Store 而且匹配 pattern 的每个 action 上派生一个 saga。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)
);
};
复制代码