Reputation: 95
Can I use a selector from a reducer?
I have a code similar to that:
case Action Types.ACTION: {
const loading = getIsLoading(state)
return {
atribute1: false,
attribute2: action.payload,
}
}
default: {
return state;
}
}
}
export const getState = createFeatureSelector<State>('feature');
export const getIsLoading = createSelector(
getState,
state => state.loading
);
When I dispatch a action at first I get a error like that: "can't read 'loading' of undefined.
Where is my mistake? Something wrong with my approach?
Upvotes: 2
Views: 6634
Reputation: 12552
Like I've stated in the comment: It's a best practice not to duplicate information in the state. If you need to call a selector in a reducer it looks like you'll do just this.
You can avoid doing this by creating a third, higher order, reducer that will return whatever is needed from the existing ones.
So you have the getIsBusy reducer and you create another one that will just return the new data from your state, the one where you wanted to read isBusy:
export const getAttribute = createSelector(
getState,
state => state.attribute
);
Now you have getIsBusy and getAttribute as selectors and you can create a third one where you can place whatever logic you need:
export const getHigherOrderSelector = createSelector(
getIsBusy,
getAttribute,
(isBusy, data) => {
return { isBusy, data };
// Or whatever other processing you might want to do here
}
);
Upvotes: 2