Reputation: 2429
Let's say there is a tree
in the state of my react-redux app and tree
belongs to myReducer
. In many cases I need this tree flattened, so I've got a selector:
const getTree = state => state.myReducer.tree;
export const getFlatNodes = createSelector(
[getTree],
(tree) => flattenTree(tree)
);
And now I need to access the flattened tree in an action
import { getFlatNodes } from 'path/to/selectors';
function myReducer(state = defaultState, action) {
switch (action.type) {
case SOME_ACTION:
const flattenedTree = getFlatNodes(state);
return {
...state,
smth: getSmthFromFlattenedTree(flattenedTree)
};
}
}
This code will not work as expected since state
in the reducer is just a slice of the app state. A simple workaround I came up with is to wrap state
to make the passed parameter compatible:
import { getFlatNodes as _getFlatNodes } from 'path/to/selectors';
const getFlatNodes = myReducer => _getFlatNodes({ myReducer });
The code works, although it looks quite hacky and I'm not sure if it won't cause any issues.
Does anybody have any idea why and how it can be done better or my approach is good enough already?
Upvotes: 1
Views: 1418
Reputation: 1170
Maybe if you make that in your action
const someAction = () => (dispatch, getState) => ({
type: 'SOME_ACTION',
payload: getFlatNodes(getState())
// payload: getSmthFromFlattenedTree(getFlatNodes(getState()))
});
then in your reducer
function myReducer(state = defaultState, action) {
switch (action.type) {
case SOME_ACTION:
return {
...state,
smth: getSmthFromFlattenedTree(action.payload)
};
}
}
Upvotes: 1