首先必須知道幾個重點
Redux 不會管你是否同步,想要更新 store ,就必須呼叫 dispatch()
Redux 原始碼中,dispatch function 的實作是此 function 會回傳其第一個參數
1
2
| // 也就是若執行以下這行,res 等於 action
const res = dispatch(action)
|
- 使用 redux-thunk 的話,若 action 為 function,thunk 會執行 action 並塞 dispatch 和 getState 作為參數:
action(dispatch, getState)
知道以上幾點,就能完全透過原生的 Promise 來實作出有先後順序的action
範例一: 等待 API 結果的 action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // 這是一個 action creator,回傳一個 action
export const listData = (params) =>
// 因為 action creator 製造出的 action 是 function
// dispatch 這個 action 時,redux-thunk 就會注入兩個參數 dispatch 和 getState
(dispatch, getState) => {
// 發送一個物件 action ,改變 loading 狀態
dispatch({ type: Actioin.LOADING });
// 回傳一個 Promise
return getDataApi(params)
.then((res) => {
// 當 promise resolved,表示資料載入完成,此時發送 action 改變 store
dispatch({ type: Action.LOADED, payload: res })
})
.catch((e) => {
dispatch({ type: Action.LOAD_FAIL})
})
}
|
當有了上面的 listData action creator
1
2
| // 此時,data 等於 getDataApi(params) 這個 Promise
const data = await dispatch(listData(params));
|
範例二: 需先取得其他 API 的結果,再做其它事
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| export const waitListData = () =>
(dispatch, getState) => {
// 發送一個物件 action ,改變 loading 狀態
dispatch({ type: Actioin.LOADING });
// 回傳一個 Promise
return dispatch(listData())
.then(() => {
// promise 有先後順序
// 這個 block 一定是 listData.then() 執行完之後,再執行的
// 故可以取得最新的 data
const latestData = getState().data;
// 接著就可以拿 latestData 做其他事了
dispatch(closeLoadingMask());
})
}
|
此時,發送這個 action dispatch(waitListData())時會做的事有:
- dispatch(listData())
- 等 1. 的 promise resolved
- 進入 waitListData 的 then