最近在初學redux,也接着學了redux裡的中間件。
對于redux,本來 store.dispatch 隻能派發的是一個對象給store。
加了 redux 中間件後:其實是對 store.dispatch 方法做了更新;更新後可接收對象,也可接收函數,使得可處理異步代碼了
如果派發的的是對象,則中間件會直接傳給store;如果派發的是函數的話,則會先執行這個函數
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9E1TxklaNRTTE9ke4wmYwhGWhxGZzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuAjN1UjNxMjMzAzNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
注意:這裡的中間件指的是 store 和 action 的中間
常見的 redux 中間件 :redux-thunk 和 redux-saga 都是處理異步的
前者是通過把異步代碼放在action裡,後者是把異步代碼單獨放在一個檔案裡
先将 redux-thunk 中間件
Redux-thunk
Redux-thunk思想: 異步請求放到action裡
安裝:
npm install redux-thunk
引入:
在建立store的地方引入這個中間件
即在store目錄下的 index.js 引入react 的 applyMiddleware 和 redux-thunk,
然後在用
createStore ()
方法中,設第二個參數:通過
applyMiddleware ()
方法使用 redux-thunk 這個中間件
//栗子
import {createStore, applyMiddleware} from 'redux'
import reducer from './reducer.js'
import thunk from 'redux-thunk'
export default createStore(
reducer,
applyMiddleware(thunk)
);
注:Chrome插件也是屬于中間件, 如果也想擴充 redux-devtools (也原本是放createStore第二個參數) 因為多使用了一些中間件,比如 redux-thunk 後,則createStore()的第二個參數的 applyMiddleware() 不能是redux-devtools 擴充Chrome插件的那些代碼了
若既想要使用 redux-devtools 這個 Chrome 擴充插件,又想使用中間件的話
怎麼辦:GitHub 的 redux-devtools-extension 提供了解決方法
https://github.com/zalmoxisus/redux-devtools-extension
import {createStore, applyMiddleware, compose} from 'redux'
import reducer from './reducer.js'
import thunk from 'redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(thunk)
);
const store = createStore(reducer, enhancer);
export default store
使用: 在action中使用redux-thunk
本來 action/ actionCreateor.js 應該傳回的是對象,使用了redux-thunk 後則也可return 傳回一個函數了,在這個函數裡去寫異步代碼(如ajax請求)
由于 action 此時是函數了,是以 react 會去執行這個函數;
在這個函數裡如果想把資料更新到 store 上的話,又是同樣的 store.dispatch (一個action),不過由于此時這個return 傳回的函數接收到的參數就是store.dispatch方法,則可直接dispatch(action對象)
// 栗子
// 元件裡
componentDidMount(){
const action = getTodolist();
store.dispatch(action)
}
// actionCreateor.js檔案
export const initListAction =(data)=>({
type: INIE_TODOLIST,
value: data
})
export const getTodolist =()=>{
return (dispatch)=>{
axios.get('./list.json').then((res)=> {
const data = res.data;
const action = initListAction(data);
dispatch(action)
})
}
}
// reducer.js 檔案裡
export const initListAction =(data)=>({
type: INIE_TODOLIST,
value: data
})
我的總結思路:
先
store.dispatch
一個函數,這個函數傳回的也是函數A,
在這個傳回的函數A裡寫的是異步的代碼,和進一步的真正的action事件的派發(第二次store.dispatch(),且派發的這個對象的資料就是來自異步後的資料)