Wendell Liu
Jun 13, 2016 · 5 min read

讓你的Action能作更多 — Redux-Thunk

延續著自己寫的Redux Middleware大略架構,接下來要來介紹Redux-Thunk。本篇除了介紹Redux-Thunk在作些什麼外,也希望能稍微review React-Thunk中的原始碼(因為很短?)。


首先,何謂thunk?問問維基百科吧!

In computer programming, a thunk is a subroutine that is created, often automatically, to assist a call to another subroutine.

簡而言之,thunk為一個能在其中呼叫另一個子程序(subroutine)的子程序。嗯…似乎有點拗口。簡單的說,若以function的作為例子,thunk就是一個function的內部會去呼叫另一個function,也就是再包裝的概念。

將這個概念用在Redux-Thunk上,便是包裝一個action creator為一個thunk。原生概念的action creator是回傳一個action(object);而若是「thunk化」的action creator,則回傳一個function。接下來就如同上一段所說,在這個回傳的function中,我們可以複雜化我們的dispatch邏輯。且看一段範例代碼:

在這個例子中,我們設計一個function,它回傳了一個輸入參數為dispatch和getState的function。在這個回傳的function中我們做了一些事情,也分別dispatch另外兩個action。

聽起來似乎有點類似上一篇介紹的Middleware概念。不過Middleware是雷同pipeline的概念,每每app在dispatch時都會做出指定的動作,而Thunk則是聚焦在更小範疇的action本身。

這很適合用來作些什麼呢?在Redux的官方文件,其中的Async Actions這一章節便使用了Thunk。

若我們要在Redux的架構下,作ajax fetch會遇到非同步的問題。由於我們無法直接在action creator回傳的object直接call function來得到fetch回來的值。可以參考下面簡單的非同步結果(請看Result內div中的值)。由於foo中回傳的bar在return之時是為’before’,並不會是等到setTimeout結束後在被assign的’after’。

此時,Redux官方文件就正式介紹Thunk出場了。藉著搭配fetch的promise特性,在獲得、處理資料後,把資料傳進另一個一般的action creator,並且dispatch。(請看以下節錄的程式碼)

from http://redux.js.org/docs/advanced/AsyncActions.html

除了非同步的用法外,實際上諸如:一次dispatch多個action、加log、先把資料處理後再dispatch等需求都能簡單使用thunk。由於以包裹的方式來讓你的action更添風采非常的方便,更必須要小心不要過度的包裹,並且仍要盡能的讓每一個action單純化。


再我們理解什麼是Thunk,並且這個概念如何在Redux系統的action creator實做後,那到底dispatch這個function是如何知道我們action creator回傳的究竟是pure object(action)還是function(thunk)呢?

Image for post
Image for post
surprised dog

這也就是React-Thunk這個專案的內容了。實際上這個專案不是提供任何thunk讓大家使用,而是一個Redux Middleware。這個Middleware改造了你的dispatch,讓他有能力判斷送進去的東西是一個pure object還是function。

原始碼中,首先判斷是否是function:

if (typeof action === ‘function’){}

如果不是function,那自然就是一個pure object,利用next(本質上就是dispatch)送出,就是什麼都不做的意思;而若是function,則把這個thunk會需要的dispatch、getState和其他arguement送給thunk,讓它做你所指定它做的事情。

經由這個Redux Middleware我們就能夠毫無顧忌(?)的不分action creator或thunk都把他們通通dispatch。

Image for post
Image for post

總結:

  1. Thunk是一個以action為本的包裹器
  2. 在Redux中藉由Redux-Thunk這個Redux Middleware讓我們可以在使用時不去區分pure action creator還是thunk action creator

Frochu

Frochu — Frontend Ochu ,程式碼的黑手,親手實作的前端知識推動者

Wendell Liu

Written by

A Frontend Developer in honestbee. Fullstack Engineer and Functional Programming enthusiast. Love the quote "Ideas are bulletproof."

Frochu

Frochu

Frochu — Frontend Ochu ,程式碼的黑手,親手實作的前端知識推動者

Wendell Liu

Written by

A Frontend Developer in honestbee. Fullstack Engineer and Functional Programming enthusiast. Love the quote "Ideas are bulletproof."

Frochu

Frochu

Frochu — Frontend Ochu ,程式碼的黑手,親手實作的前端知識推動者

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store