redux 提供了类似后端 Express 的中间件概念.
最适合扩展的是 redux 中的 store.dispatch 方法, 中间件实际就是通过 override redux 的 store.dispatch() 完成
将 action -> reducer 过程变为 action -> middlewares -> reducer 如:
- let next = store.dispatch;
- store.dispatch = function dispatchAndLog(action) {
- console.log('dispatching', action);
- next(action);
- console.log('next state', store.getState());
- }
添加中间件
redux 提供了 applyMiddleware 方法便于添加中间件
applyMiddleware 的源码:
- export default function applyMiddleware(...middlewares) {
- middlewares = middlewares.slice()
- middlewares.reverse()
- // Transform dispatch function with each middleware.
- middlewares.forEach(middleware =>
- // 由于每次 middle 会直接返回返回函数, 然后在这里赋值给 store.dispatch,
- // 下一个 middle 在一开始的时候, 就可以通过 store.dispatch 拿到上一个 dispatch 函数
- store.dispatch = middleware(store)
- )
- }
通过 middleware 将 store.dispatch 进行扩展
middleware 会返回一个函数:
return store => dispatch => action => {}
异步操作
同步操作只要发出一种 Action 即可, 异步操作通常需要发出多种 Action(开始, 成功, 失败)
异步操作有 2 种 Action 写法 (3 种 type 或者 添加 erro 和 response 字段)
异步操作的 state 结构调整
Action 写法:
- // 写法一: 名称相同, 参数不同
- { type: 'FETCH_POSTS' }
- { type: 'FETCH_POSTS', status: 'error', error: 'Oops' }
- { type: 'FETCH_POSTS', status: 'success', response: { ... } }
- // 写法二: 名称不同
- { type: 'FETCH_POSTS_REQUEST' }
- { type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
- { type: 'FETCH_POSTS_SUCCESS', response: { ... } }
异步 State 结构:
- let state = {
- // ...
- isFetching: true,// 正在获取数据
- didInvalidate: true,// 是否过期
- lastUpdated: 'xxxxxxx'// 上次更新时间
- };
使用中间件
使用
createStore(reducer, enhancer)
或
createStore(reducer, preloadedState, enhancer)
applyMiddleware 的参数为中间件, 某些中间件有顺序要求如: logger
redux-logger
redux-logger 可清晰记录 preState action nextState time 等信息.
示例:
- import { createStore, applyMiddleware } from 'redux'
- import createLogger from 'redux-logger'
- import rootReducer from './reducers'
- let store = createStore(rootReducer, applyMiddleware(createLogger));
- redux-thunk
redux-thunk 用来优化 redux 中的异步操作.
在 store.dispatch 的方法参数只支持 js 对象 (即 Action), 使用 redux-thunk 将支持参数为一个函数.
函数签名:
(dispatch, getState) => {}
示例:
- import { createStore, applyMiddleware } from 'redux'
- import thunkMiddleware from 'redux-thunk'
- import rootReducer from './reducers'
- let store = createStore(rootReducer, applyMiddleware(thunkMiddleware));
- store.dispatch( dispatch => {
- dispatch({type:'CLICK_START',data:res})
- fetch('xx')
- .then(res => dispatch({type:'CLICK_END',data:res}));
- } )
实际上, redux-thunk 的作用是让 Action Creator 方便可以返回函数, 这样让项目中的同步异步 Action Creator 调用可以保持一致
支持异步的还有 redux-promise 和 redux-saga 等
来源: https://www.cnblogs.com/neverc/p/9071587.html