redux的中间件 官网
在了解中间件之前需要对redux等有基础了解
概念
Redux middleware 被用于解决不同的问题,它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。 你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
使用
以 redux-logger 为例:
1.安装
npm install redux-logger redux-promise redux-thunk redux-saga -S
引用
store/index.js
import { legacy_createStore as createStore, applyMiddleware } from "redux";
import reducer from './reducers'
import reduxLogger from 'redux-logger'
import reduxThunk from 'redux-thunk'
const store = createStore(
reducer,
applyMiddleware(reduxLogger, reduxThunk)
)
export default store
2.使用步骤
- 从redux内解构出applyMiddleware
- 导入需要使用的中间件 例如:redux-logger
- 中间件传入 applyMiddleware 作为createStore()的第二个参数
上面这一部分,等于 redux-logger 中间件添加完成✅
整体项目例子
store内的全量代码 Redux工程化开发
页面内容代码:React-redux 插件 了解及使用
但是中间件内部用法一致可以不看例子,具体内部的截图内容来源是这个例子代码
redux-logger
用于每一次派发,在控制台输出派发日志,方便对redux操作进行调试。 输出内容有:派发之前的状态、派发行为、派发后的状态。
添加 redux-logger 中间件后,派发了会进行数据记录。
redux-thunk
在不使用中间件之前,redux执行都是同步的,如果需要进行处理等操作,就需要用到中间件, 这里的 redux-thunk/ redux-promise 均可进行异步派发
redux-thunk 用于实现异步派发,(每一次派发的时候,需要传递给reducer的action对象中的内容,是需要异步获取的)
当内部不使用dispatch的情况时:内部为同步操作,直接修改数据,没有可以添加的内容
// 初始代码
add() {
return {
type: TYPES.COUNT_INCREASE
}
}
添加 redux-thunk 代码实现:
const countAction = {
add() {
return async (dispatch, getState) => {
// 代码内部操作
}
}
}
const countAction = {
add() {
return async (dispatch, getState) => {
// dispatch 是用来派发 action
// getState 用于获取数据
await delay() // delay 模拟异步操作
dispatch({
type: TYPES.COUNT_INCREASE
})
}
}
}
运行结果:
可以看到,在异步操作完成后,我们基于基于真正的dispatch实现派发,通知reducer执行,实现状态更改!
原理
根据上方的运行截图可以看到: 在点击增加后,dispatch派发了两次
1.第一次执行返回一个函数,内部给函数设置了一个type属性,属性值不会和reducer内的逻辑匹配
第一次派发 dispatch函数,type和reducer内的逻辑不匹配,所以无任何状态改变
2.把返回的函数执行,把派发的dispatch传递给函数
在dispatch内进行派发 store内获取到的是传递过去的函数
redux-promise
也是实现异步派发操作的中间件,写法和redux-thunk有差异
引入方法同上方操作
const countAction = {
async sub() {
await delay(3000)
return {
type: TYPES.COUNT_DECREASE
}
}
}
点击减少运行:
原理
第一次点击反对按钮:
dispatch(voteAction.oppose())
- 此dispatch也是被重写的,传递进来的是promise 实例:
-
没有type 屬性,但是不报错
-
也不会通知reducer执行
- 但是他会 监听 voteAction.oppose 执行的返回值 「promise 实例」
等待实例为成功的时候,它内部会自动再派发一次任务:
-
用到的是store.dispatch派发「会通知reducer执行了」
-
把实例为成功会的结果「也就是我们返回的标准的action对象』传递给reducer,实现状态更改!!
二者区别(redux-thunk 和redux-promise)
reduxpromise和redux thunk中间件,都是处理异步派发的,他们相同的地方
- 都是派发两次
-
第一次派发用的是,重写后的dispatch:这个方法不会去校验对象是否有 type属性;也不会在乎传递的对象是否为标准普通对象!!
-
此次派发,仅仅是为了第二次派发做准备
-
redux-thunk:把返回的函数执行,把真正的dispath传递给函数
-
redux-promise:监听返回的promise实例,在实例为成功后,需要基于真正的disptch,把成功的结果,再进行派发!!!
区别: redux-thunk 第二次派发是手动处理 redux-promise 是自动处理
代码
countAction.js 的全量代码 可以和它对比下 Redux工程化开发
路径:store/action/countAction.js
import * as TYPES from '../action-types'
const delay = (interval = 1000) => {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, interval)
})
}
const countAction = {
// 初始写法
// add() {
// return {
// type: TYPES.COUNT_INCREASE
// }
// }
// redux-thunk 写法
add() {
return async (dispatch, getState) => {
await delay()
dispatch({
type: TYPES.COUNT_INCREASE
})
}
},
// redux-promise 写法
async sub() {
await delay(3000)
return {
type: TYPES.COUNT_DECREASE
}
}
}
export default countAction