用Redux Thunk 來處理非同步action

Joe Chang
Coding Hot Pot
Published in
Jan 4, 2021
photo by @momentance

Redux Thunk的目的就是為了實踐middleware,讓action能做更多的事,想必大家都曾經看過這個錯誤,當action為非同步的時候,就會報錯,Redux Thunk就是為了解決這個問題而生

來看一下Redux Thunk的原始碼

function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}

return next(action);
};
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

你沒看錯,就只有這樣。

原本的action creator 都是回傳action object,在Redux Thunk裡面會檢查若action不是object而是function,就會執行function後再將action往下傳,直到回傳object才會進去reducers

那麼接著來實作一下,情境很簡單,call api拿到資料後dispatch更新資料,讓畫面依據資料長出列表

記得要先安裝

npm install redux-thunk --save

store的部分因為比之前複雜,就從index.js抽離出來獨立

createStore可以接受三個參數(reducer、初始state、applyMiddleware),而applyMiddleware又可以傳入三個參數(thunk、promise、logger

順帶一提,我有另外安裝redux-logger,會在action觸發和state變化時自動印出log,個人覺得在除錯方面還蠻方便的

index.js 將store傳入

這邊為了簡單做個練習,所以只寫了一個action,處理資料接收,fetchPosts在拿到api資料後dispatch receivePosts(json.data),可以發現fetchPosts是回傳一個函式

getBikeList 可以同時拿到getState和dispatch方法

reducersBike.js

經過Middleware處理後,最後將資料傳給reducer,改變state之後重新渲染UI畫面

一切準備就緒之後,在componentDidMount階段dispatch getBikeList,在還沒拿到資料等待api回應之前先顯示loading,(本來是要接高雄Youbike據點的api,但api時好時壞,只好改接市場資料orz

api的key居然是中文,第一次看到

下面這部分就跟以往的redux一樣

最後成功拿到列表!

除了react-thunk之外,再處理Middleware非同步這塊,Redux Saga也會是個不錯的選擇,日後有機會再來分析兩者的差異。

--

--

Joe Chang
Coding Hot Pot

前端工程師,唯有非常努力,才能看起來毫不費力