注1:本文主要根據 “自述|redux中文文件” 學習的個人總結記錄。也是是為了更快更好的學習和接受redux的操作,更好的應用的專案中。原文件地址:http://www.redux.org.cn/
注2:本文較長,可能會需要花一點時間去閱讀和理解.
非同步Action
之前在開發的時候,關於在action creator中傳入dispatch,然後通過非同步請求後再dispatch action的方式觸發reducer改變state,一直沒有弄明白dispatch是如何傳到action creator中的,自從研究文件後才大致弄清楚了。
今天我們就來弄清楚這些疑惑。如下就是一個在action creator中通過非同步action的操作方式來觸發reducer:
export function indexQuestion(data) {
return (dispatch) => {
Apis.indexQuestion(data) //發起一個介面請求
.then((res)=> {
dispatch({
type: Types.GET_INCEX_DATA,
store: res.data
});
}, (err)=> {
dispatch({
type: Types.ERROR_MESSAGE
});
})
}
}
從上面的程式碼我們要注意到是發起請求的時候和請求收到響應的時候,在這兩個時候都可以通過dispatch去改變state狀態。如上例項程式碼主要是在請求響應後分別對成功和失敗做了處理。
那麼我們是如何將action和非同步請求結合到一起的呢?標準的做法就是通過redux-thunk中介軟體(熟悉express的同學應該都瞭解什麼叫做中介軟體吧)。通過使用指定的中介軟體,action creator除了返回普通的action物件,現在還可以返回函式,這個action函式就稱為了“thunk”(什麼叫thunk我還不太清楚….希望有人幫忙解釋下)
那麼中介軟體是起什麼作用的呢?上面說了引入中介軟體後,action建立函式可以在函式體內返回其他函式了。那麼當action中返回的其他函式的時候就會被Redux Thunk中介軟體執行,*會把dispatch方法通過引數的形式傳給該函式。如下:
export function getMajor(){
return (dispatch) => { //返回一個函式,dispatch通過引數的形式傳入
Apis.major().then((res)=>{
dispatch({ //請求成功的時候dispatch action改變state
type: Types.MAJOR_INFO,
store: res.data
})
}, (error) => {
dispatch({ //請求失敗的時候dispatch另外一個action改變state
type: Types.ERROR_MESSAGE,
error
})
})
}
}
我們是如何在 dispatch 機制中引入 Redux Thunk middleware 的呢?我們使用了 applyMiddleware(),如下:
//這是官方文件中例子,稍微刪掉一些這樣看起來更清楚。
import thunkMiddleware from `redux-thunk` //引入thunk
import { createStore, applyMiddleware } from `redux`
import { selectSubreddit, fetchPosts } from `./actions`
import rootReducer from `./reducers`
const store = createStore(
rootReducer,
applyMiddleware(
thunkMiddleware, // 允許我們 dispatch() 函式
)
)
如上,通過applyMiddleware引入了thunkMiddleware,這樣就可以在action中再次dispatch action。
這可以讓我們逐步開發複雜的非同步控制流,同時保持程式碼整潔如初。
關於如何在action中傳入dispatch可以繼續dispatch action的原因就是這樣。
中介軟體(Middleware)
引用文件中的一句話,它提供的是位於 action 被髮起之後,到達 reducer 之前的擴充套件點。你可以利用 Redux middleware 來進行日誌記錄、建立崩潰報告、呼叫非同步介面或者路由等等。