2016-02-13 45 views
4

我需要從兩個或多個減速器訪問用戶可編輯狀態。有沒有辦法訪問由另一個減速器控制的狀態,而不通過動作的有效載荷將它傳遞給減速器?我想避免讓每個操作都將用戶設置發送給reducer。如何在兩個或多個減速器之間共享只讀狀態

國家

{ 
    userSettings: { 
    someSetting: 5 
    }, 
    reducer1State: { 
    someValue: 10 // computed with userSettings.someSetting 
    }, 
    reducer2State: { 
    someOtherValue: 20 // computed with userSettings.someSetting 
    } 
} 

從reducer1我想使用類似以下的userSettings.someSetting獲得:

function update(state={}, action) { 
    if (action.type === constants.REDUCER_1.CALCULATE) { 
    return _.assign({}, state, { 
     someValue: 2 * GETSTATE().userSettings.someSetting 
    }); 
    } 
... 

我不想有從發送userSettings這樣的動作:

export function calculate(userSettings) { 
    return { 
    type: constants.REDUCER_1.CALCULATE, 
    userSettings: userSettings 
    }; 
} 
+0

你可以使更多的狀態可見的減速器之一,而不是隻傳遞一個狀態的子集? – danielepolencic

+1

基本上所有reducer都需要userSettings,所以我正在尋找一種方法將其默認傳遞給所有reducer。 –

回答

5

Redux的黃金法則之一是,如果可以從其他狀態計算數據,則應該儘量避免將數據置於狀態,因爲這會增加獲取不同步數據的可能性,例如,臭名昭着的未讀消息計數器告訴你,如果你真的沒有未讀消息。

您可以使用Reselect來創建您在connectStateToProps函數中使用的memoized選擇器,以獲取您的派生數據(例如,沿着這條線:

const getSomeSettings = state => state.userSettings.someSetting; 
const getMultiplier = state => state.reducer1.multiplier; 

const getSomeValue = createSelector([getSomeSettings, getMultiplier], 
    (someSetting, multiplier) => { 

}); 

const mapStateToProps(state) => { 
    return { 
     someValue: getSomeValue(state) 
    } 
} 

const MyConnectedComponent = connect(mapStateToProps)(MyComponent); 
+0

我還是不明白這是如何解決不得不通過行動傳遞給reducer的問題的。在沒有第一次訪問共享狀態的情況下,reducer如何使用getSomeValue? –

+1

問題是,如果數據是可以從其他現有狀態計算的數據,則不會將數據存儲在共享狀態中。因此,在上面的例子中,'getSomeValue'不存儲共享狀態的任何東西,它從共享狀態('someSetting'和'multiplier')獲得它需要的數據,並根據'someSetting'和''someSetting''計算'someValue'。 multiplier'。 –

+0

@Hummlas我努力尋找使用userSettings不創建派生數據並且不能創建的場景。 Reselect已經完美地用於我的用例。謝謝! –

相關問題