最近在初學(xué)redux其爵,也接著學(xué)了redux里的中間件。
對(duì)于redux伸蚯,本來(lái) store.dispatch 只能派發(fā)的是一個(gè)對(duì)象給store摩渺。
加了 redux 中間件后:其實(shí)是對(duì) store.dispatch 方法做了升級(jí);升級(jí)后可接收對(duì)象剂邮,也可接收函數(shù)摇幻,使得可處理異步代碼了
如果派發(fā)的的是對(duì)象,則中間件會(huì)直接傳給store挥萌;如果派發(fā)的是函數(shù)的話绰姻,則會(huì)先執(zhí)行這個(gè)函數(shù)
注意:這里的中間件指的是 store 和 action 的中間
常見(jiàn)的 redux 中間件 :redux-thunk 和 redux-saga 都是處理異步的
前者是通過(guò)把異步代碼放在action里,后者是把異步代碼單獨(dú)放在一個(gè)文件里
先將 redux-thunk 中間件
Redux-thunk
Redux-thunk思想: 異步請(qǐng)求放到action里
安裝:
npm install redux-thunk
引入:
在創(chuàng)建store的地方引入這個(gè)中間件
即在store目錄下的 index.js 引入react 的 applyMiddleware 和 redux-thunk,
然后在用 createStore ()
方法中引瀑,設(shè)第二個(gè)參數(shù):通過(guò) applyMiddleware ()
方法使用 redux-thunk 這個(gè)中間件
//栗子
import {createStore, applyMiddleware} from 'redux'
import reducer from './reducer.js'
import thunk from 'redux-thunk'
export default createStore(
reducer,
applyMiddleware(thunk)
);
注:Chrome插件也是屬于中間件, 如果也想擴(kuò)展 redux-devtools (也原本是放createStore第二個(gè)參數(shù)) 因?yàn)槎嗍褂昧艘恍┲虚g件狂芋,比如 redux-thunk 后,則createStore()的第二個(gè)參數(shù)的 applyMiddleware() 不能是redux-devtools 擴(kuò)展Chrome插件的那些代碼了
若既想要使用 redux-devtools 這個(gè) Chrome 擴(kuò)展插件憨栽,又想使用中間件的話
怎么辦: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
本來(lái) action/ actionCreateor.js 應(yīng)該返回的是對(duì)象帜矾,使用了redux-thunk 后則也可return 返回一個(gè)函數(shù)了翼虫,在這個(gè)函數(shù)里去寫異步代碼(如ajax請(qǐng)求)
由于 action 此時(shí)是函數(shù)了,所以 react 會(huì)去執(zhí)行這個(gè)函數(shù)黍特;
在這個(gè)函數(shù)里如果想把數(shù)據(jù)更新到 store 上的話蛙讥,又是同樣的 store.dispatch (一個(gè)action),不過(guò)由于此時(shí)這個(gè)return 返回的函數(shù)接收到的參數(shù)就是store.dispatch方法灭衷,則可直接dispatch(action對(duì)象)
// 栗子
// 組件里
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
})
我的總結(jié)思路:
先 store.dispatch
一個(gè)函數(shù)次慢,這個(gè)函數(shù)返回的也是函數(shù)A,
在這個(gè)返回的函數(shù)A里寫的是異步的代碼翔曲,和進(jìn)一步的真正的action事件的派發(fā)(第二次store.dispatch()迫像,且派發(fā)的這個(gè)對(duì)象的數(shù)據(jù)就是來(lái)自異步后的數(shù)據(jù))