这里的中间件指的是action和store之间
redux-thunk
redux-thunk这个中间件就是对dispatch方法的一个升级,如果dispatch中传递的是一个对象,会直接传递给store;如果是一个方法,会先执行这个方法
1、使用之前先安装一下
:
npm install redux-thunk
2、配置一下redux-thunk
redux-thunk和redux-devtools一样都是一个中间件,需要在store中配置,可以查阅github:
https://github.com/zalmoxisus/redux-devtools-extension
https://github.com/reduxjs/redux-thunk
当使用了redux-thunk后还要使用redux扩展工具,这里的配置就不能像之前那样配置了,按照github中的步骤即可
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import Reducer from './reducer'
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
const enhancer = composeEnhancers(
applyMiddleware(thunk),
)
// window下有这个变量则执行调试工具
const Store = createStore(
Reducer,
enhancer
)
export default Store
没有使用redux-thunk之前action只能返回一个对象,现在可以用thunk返回一个函数了
actionCreators.js
export const initListAction = (arr) => ({
type: initList,
arr
})
export const getInitListAction = (arr) => ({
type: getInitList,
arr
})
//使用redux-thunk后可以返回一个函数
export const getServeData = () => {
return (dispatch) => {
axios.post('https://XXXXXXXXXXXXX/test/charging/products/list').then(res => {
const data = []
res.data.data.records.map(item => {
console.log(item)
data.push(item.productTitle)
})
dispatch(initListAction(data))
}).catch(err => {
})
}
}
使用是时候在页面引入,调用即可
import { getServeData, getInitListAction } from '../store/actionCreators'
componentDidMount(){
Store.dispatch(getServeData())
}
redux-saga
redux-saga和saga不同,他是把异步的操作单独的放在一个文件中进行管理
github地址:
https://github.com/redux-saga/redux-saga
安装:
npm install redux-saga
新建saga.js
import {
call,
put,
takeEvery,
takeLatest
} from 'redux-saga/effects'
import {
getInitList
} from './actionTypes'
import axios from 'axios'
import {
initListAction
} from './actionCreators'
function* getInitData() {
try {
// 等到axios请求完成后将结果存到result中
const result = yield axios.post('https://proxy01.hnchengyue.com/test/charging/products/list')
console.log(result)
const data = []
result.data.data.records.map(item => {
data.push(item.productTitle)
})
const action = initListAction(data)
// 等到action执行完后再执行put
yield put(action)
} catch (error) {
console.log(error)
}
}
function* mySaga() {
//只要接收到getInitList这个类型,执行getInitList方法
yield takeLatest(getInitList, getInitData);
}
export default mySaga
这里注意不能像以前axios请求那样子写了,需要用yield,当请求错误的时候统一在catch里面处理
最后在todolist的componentDidMount中dispatch一个getInitListAction即可
配置saga
使用redux-saga这个中间件也要在store中进行配置
import { createStore, applyMiddleware, compose } from 'redux'
// import thunk from 'redux-thunk'
import Reducer from './reducer'
import saga from './saga'
import createSagaMiddleware from 'redux-saga'
const sagaMiddleware = createSagaMiddleware()
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
const enhancer = composeEnhancers(
applyMiddleware(sagaMiddleware),
)
// window下有这个变量则执行调试工具
const Store = createStore(
Reducer,
enhancer
)
//一定要放在createStore后面,不然会报错
sagaMiddleware.run(saga)
export default Store
使用
只需要在componentDidMount中引入getInitListAction并派发
import { getServeData, getInitListAction } from '../store/actionCreators'
componentDidMount(){
// const action = getServeData()
Store.dispatch(getInitListAction())
//store发生变化就更新
Store.subscribe(this.handleStoreChange)
}