2017-05-07 41 views
1

我正在使用Reduce的ReSwift實現來編寫應用程序。我想知道,何時使用動作創作者,爲什麼?何時,爲什麼以及如何在Redux中使用Action Creators?

讀完tutorial之後,我就像創造者一樣填充只是在檢查內部狀態後才創建動作。例如,我有一個按鈕,在用戶按下它之後,如果我處於狀態A,我想啓動一些進程。所以,我必須編寫一個動作創建器,它將檢查當前狀態,然後返回正確的動作,或不動作在所有。然後從同一個地方派發這個動作。

對嗎?我會很感激任何例子。

第二個問題 - 我必須在哪裏實現它?

回答

2

我在我的博客文章Idiomatic Redux: Why Use Action Creators?中介紹了此主題。重述要點:

  1. 基本抽象:不是在需要創建同一類型的動作的每一個組成部分寫入動作類型的字符串,把邏輯在一個地方創建行動。
  2. 文檔:該函數的參數可用作指導進入操作所需的數據。
  3. 簡潔和乾燥:可能有一些更大的邏輯用於準備操作對象,而不是立即返回它。
  4. 封裝和一致性:始終使用動作創建者意味着組件不需要知道創建和分派動作的任何細節,以及它是簡單的「返回動作對象」函數還是複雜的thunk功能與衆多的異步調用。它只是調用this.props.someBoundActionCreator(arg1, arg2),並讓動作創建者擔心如何處理事情。
  5. 可測試性和靈活性:如果某個組件僅調用一個作爲prop傳入的函數而不是顯式引用dispatch,則可以輕鬆地爲傳入該函數的模擬版本的組件編寫測試。它還可以在其他情況下重用組件,甚至可以使用Redux以外的組件。
+0

好吧,我想我明白了。仍然 - 你可以請回答這個問題:我有一個按鈕,必須開始發送信息的過程。但從邏輯上講,只有當我的狀態支持這個發送時它才能發送它。否則,它必須發送其他操作 - 給用戶的消息,它還沒有準備好。我必須在哪裏放置這種行爲決定的邏輯? –

+0

這對thunk函數來說是一個很好的用例。 Thunk可以訪問'getState()',所以Thunk可以檢查狀態值並決定是否派發。根據我的評論,這個組件只是調用'this.props.someFunction()',並且不必再擔心它。我在https://gist.github.com/markerikson/ea4d0a6ce56ee479fe8b356e099f857e有一些常見的thunk模式示例。 – markerikson

1

動作創建者只需創建由您的商店派發的動作,以供您的Reducer處理。

爲方便起見,您應該使用Action Creator來防止每次需要分派操作時聲明對象。例如,假設下面的例子:

<button onClick={() => { dispatch({ type: 'MY_ACTION'); }}> 

它是清潔寫:

<button onClick={() => { dispatch(myActionCreator()); }} 

並且更易於理解了。

它在內部組件(例如React)中很有用,您可以在其中通過道具注入它們並將它們作爲普通函數(例如在按鈕單擊中)調用它們。

有幾種方法可以聲明動作創建者。沒有模式可以做到這一點。您可以創建一個名爲actions的文件,並將它們放在此文件中,您可以將它們與縮減器一起寫入。你決定。

你可以檢查documentation來澄清你的想法。你也可以看到this有趣的模式來宣佈你的動作創造者。

希望它有幫助。

+0

yes,有幫助。你能否告訴我,我應該在哪裏聲明選擇行動的邏輯,取決於狀態?例如,我想檢查我是否處於狀態A,然後執行AAction,如果我處於狀態B - BAction。 –

+0

我明白了。你目前的狀態與你的行爲沒有直接關係。您沒有針對狀態A的操作A.您的操作會改變您的狀態。你可以傳遞任何東西給他們,他們需要有一個類型屬性來標識動作。例如,您可以執行一個操作,在您的狀態下將屬性isLoading更改爲true。另一個把它改回假。你有兩個動作改變同一個屬性。您對Action A屬於狀態A沒有限制。您只需調用它們並根據需要改變狀態。 –

+0

我的意思是另一個問題:)讓我們說我有一個按鈕,必須開始發送信息的過程。但從邏輯上講,只有當我的狀態支持這個發送時它才能發送它。否則,它必須發送其他操作 - 給用戶的消息,它還沒有準備好。我必須在哪裏放置這種行爲決定的邏輯? 或者我只是發送一個動作'ButtonTapped',並在減速器中做其他的事情? –

3

Redux.js和ReSwift的行爲完全不同。

讓我先澄清一些事情,然後再回答您的問題。

消解Redux.js/ReSwift困惑在ReSwift

「行動創造者」

行動創作者是Redux.js一個相當專業的詞彙,但該類型在ReSwift像這樣定義爲V4的:

public typealias ActionCreator = (_ state: State, _ store: Store) -> Action? 

所以違背一般的建議,您必須在調度的動作點進入狀態。儘管Thunks或Epics可以在更復雜的情況下提供幫助,但您不需要Thunk實施。

那是太拗口了:)

Redux.js行動「行動創作者的幫助封裝行爲產生細節」

是對象文本。如果您要在Swift中編寫它們,Redux操作將更像Dictionary s。這就是Redux.js中的Action Creators如何爲工廠提供便利(如「工廠」,四人幫設計模式)。

雖然,ReSwift.Action類型通常以自定義值類型(struct s)實現。 ReSwift不會遇到Redux.js操作的問題。這意味着通過在ReSwift中創建類型的自定義動作,在一個函數中集中創建動作的好處就消失了。你的類型的初始化器已經提供了這個。

這描繪了一幅完全不同的圖畫。

而這可能是爲什麼ReSwift.Store.ActionCreator通過的狀態:提供任何好處。以與Redux不同的API爲代價。

應用到你的問題

例如,我有一個按鈕,用戶按下後,我想,如果我在狀態A.很,我必須寫一個行動的創建者啓動一些程序,它將檢查當前狀態,然後返回正確的操作,或根本不操作。然後從同一個地方派發這個動作。

有幾種實現方法。

如果您有權訪問商店變量以致電dispatch,那麼您也可以訪問其當前的state屬性。您可以向商店詢問該應用所在的狀態並採取相應行動。通常情況下,您會寫商店訂閱者來獲取商店更改的「推送通知」,但在這種情況下,您還可以詢問商店。

這意味着下面的是一個完全有效的實現:

let currentState = store.state 
let action: Action = { 
    if currentState.someSubstate == "A" { 
     return ActionWhenInStateA() 
    } else { 
     return ActionWhenNotInStateA() 
    } 
} 
store.dispatch(action) 

由於ReSwift Store s的不應該從不同的線程接收調度命令,你可以依靠的狀態,從1號線是相同的在最後一行,你派遣的地方。

TL; DR:您不需要​​來實現此目的。但你可以,如果你喜歡寫「東向」的代碼,靠回調代替財產查詢:

store.dispatch { state, _ in 
    if state.someSubstate == "A" { 
     return ActionWhenInStateA() 
    } else { 
     return ActionWhenNotInStateA() 
    } 
} 
相關問題