當我們在執行某個動作的時候,會直接dispatch(action),此時state會立即更新,但是如果這個動作是個異步的呢,我們要等結果出來了才能知道要更新什么樣的state(比如ajax請求),那就沒辦法了,所以此時要用異步action。
這里一定要引入redux-thunk這個庫,通過使用中間件Middleware來把從action到reducer這個過程給拆分成很多個小過程,這樣我們就能在中間隨時查找此刻的狀態以及執行一些其他動作了。具體的Middleware和redux-thunk以后再介紹,這里直接上代碼如何用,只要在store里面這樣寫就可以了:
import {createStore,applyMiddleware} from 'redux' import thunk from 'redux-thunk' import {reducers} from '../reducers/reducers' const initState = { ... }; export const store = createStore( reducers, initState, applyMiddleware(thunk) )
此時就可以在action文件里面開始寫異步action了,先上代碼:
function loginAction(data){ return (dispatch,getState) => { setTimeout(function() { if(getState(num) > 0) { dispatch(action1(data)) } else { dispatch(action2(data)) } }, 2000); } }
這個loginAction表示動作觸發2秒之后,檢測一下當前狀態num,如果此時的num>0,就dispatch第一個action1,否則dispatch第二個action2,這里模擬了一個異步的過程,在執行loginAction的時候還不知道要觸發哪個action,2秒之后才知道。這里的兩個參數dispatch和getState是中間件提供的。
最后來列舉一個常用的ajax調用的示例,這里要用到一個庫,名字比較奇怪“isomorphic-fetch”,它的用法類似於Promise的用法,直接上代碼:
import fetch from 'isomorphic-fetch'; import {serviceIpHotelMaster} from '../services/config'; import {createHashHistory} from 'history' const history = createHashHistory(); // 登錄action function loginAction(data){ return dispatch => { return fetch(`${serviceIpHotelMaster}/HostelAccount/Login?UserName=${data.userName}&PassWord=${data.password}&callback`,{method: 'get'}) .then(response => response.json()) .then(response => { if(response.ResultCode==0){ dispatch(setHotelData(response.Data)); dispatch(setToken(response.Data.Token)); history.push('/roomList'); } }) } }
這里是一個登錄的過程,fetch是這個庫的主要方法,具體用法見上面,不多說了。