Допустим, есть tree в состоянии моего приложения response-redux, а tree принадлежит myReducer. Во многих случаях мне нужно сплющить это дерево, поэтому у меня есть селектор:
const getTree = state => state.myReducer.tree;
export const getFlatNodes = createSelector(
[getTree],
(tree) => flattenTree(tree)
);
И теперь мне нужно получить доступ к сплющенному дереву в действии
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)
};
}
}
Этот код не будет работать должным образом, поскольку state в редукторе - это всего лишь часть состояния приложения. Я придумал простой обходной путь - обернуть state, чтобы переданный параметр стал совместимым:
import { getFlatNodes as _getFlatNodes } from 'path/to/selectors';
const getFlatNodes = myReducer => _getFlatNodes({ myReducer });
Код работает, хотя выглядит довольно хакерским, и я не уверен, что это не вызовет никаких проблем.
Кто-нибудь знает, почему и как это можно сделать лучше, или мой подход уже достаточно хорош?
Полезные данные действия обычно используются для передачи соответствующих данных в редуктор. В вашем случае компонент, который вызывает действие, или сам создатель действия будет использовать селектор для получения данных из состояния с помощью getSmthFromFlattenedTree(flattenedTree) и отправки действия с полезной нагрузкой: {type: "SOME_ACTION", smthFromState}





Может быть, если вы сделаете это в своем действии
const someAction = () => (dispatch, getState) => ({
type: 'SOME_ACTION',
payload: getFlatNodes(getState())
// payload: getSmthFromFlattenedTree(getFlatNodes(getState()))
});
тогда в вашем редукторе
function myReducer(state = defaultState, action) {
switch (action.type) {
case SOME_ACTION:
return {
...state,
smth: getSmthFromFlattenedTree(action.payload)
};
}
}
Можно попробовать использовать npmjs.com/package/combine-section-reducers. С помощью secion reducer у вас есть доступ ко всему состоянию в каждом subreducer