I need access to user editable state from two or more reducers. Is there a way to access state controlled by another reducer without passing it to the reducer through the action's payload? I want to avoid having every action send user settings to reducers.
State
{
userSettings: {
someSetting: 5
},
reducer1State: {
someValue: 10 // computed with userSettings.someSetting
},
reducer2State: {
someOtherValue: 20 // computed with userSettings.someSetting
}
}
From the reducer1 I would like to get at userSettings.someSetting
using something like the following:
function update(state={}, action) {
if (action.type === constants.REDUCER_1.CALCULATE) {
return _.assign({}, state, {
someValue: 2 * GETSTATE().userSettings.someSetting
});
}
...
I do not want to have to send userSettings from the action like this:
export function calculate(userSettings) {
return {
type: constants.REDUCER_1.CALCULATE,
userSettings: userSettings
};
}
How do I share state between two reducers? Do I have to use combineReducers ? The suggested structure for a Redux store is to split the state object into multiple “slices” or “domains” by key, and provide a separate reducer function to manage each individual data slice.
State is read-only Because all changes are centralized and happen one by one in a strict order, there are no subtle race conditions to watch out for.
It turns out that Redux lets us combine multiple reducers into one that can be passed into createStore by using a helper function named combineReducers . The way we combine reducers is simple, we create one file per reducer in the reducers directory. We also create a file called index. js inside the reducers directory.
One of the golden rules of Redux is that you should try to avoid putting data into state if it can be calculated from other state, as it increases likelihood of getting data that is out-of-sync, e.g. the infamous unread-messages counter that tells you that you have unread messages when you really don't.
Instead of having that logic in your reducer, you can use Reselect to create memoized selectors that you use in your connectStateToProps
function, to get your derived data, e.g. something along the line of this:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With