
Хочу Вас ознакомить со своим проектом, который позволяет осуществить данный подход.
Использование
1) Сначала, на уровне редьюсера первого уровня, подключаем саму библиотеку:
import {stateCombine, runCombine, getInitialState} from "redux-combine-deep-props";
2) Подключаем редьюсер для второго уровня:
import level2Module from "./reducer-level-2";
3) Формируем начальные значения для первого уровня:
let initialState = {
propLevel1: ...,
...
propLevelN: ...
};
4) Создаем объект комбинаций:
let combinations = {
<name prop>: {
module: level2Module
}
};
где мы задаем название будущего раздела name prop, и для него — редьюсер этого уровня,
5) Создаем функцию-обработчик текущего стейта:
let combineDeepProp = stateCombine(combinations);
let combine = runCombine(combinations, combineDeepProp);
6) Для обработки начальных значений всех уровней создаем комбинированный initial state.
const combineInitialState = getInitialState(combinations, initialState);
7) В экспортной функции-редьюсере используем комбинированный initial state, а в ее теле строго до любого изменения состояния запускаем обработчик всех комбинаций, который меняет нужным образом текущее состояние, если текущий тип экшена совпал с заданными:
export default function level1Module (state = combineInitialState, action) {
...
let newState = combine(state, action);
...
switch (action.type) {
case "....":
newState = {
...newState,
...
};
break;
...
};
...
return newState;
};
8) Модуль второго уровня оформляется по стандартной схеме, с учетом, что стейт в нем представлен в разрезе этого уровня:
let initialState = {
...
};
export default function search(state = initialState, action) {
...
switch (action && action.type) {
...
};
};
но с одним отличием — должна быть проверка на undefined текущего action. Сделано для задание initial state при первом проходе в методе getInitialState.
Заключение
Данный подход позволяет в рекурсивном режиме расширить до бесконечности текущий уровень и по «вертикали», за счет использованием в комбинациях более одного объекта:
let combinations = {
<name prop1>: {
module: level2Module1
},
...
<name propN>: {
module: level2ModuleN
}
};
и по «горизонтали», за счет использования описанного выше подхода на каждом из 2+ уровней.
→ Исходники
UPD:
Полный рефакторинг кода, большое спасибо dagen, за указание на проблему мутабельности. Теперь немного поменялся принцип использования, смотрите п.7 и п.4 — набор экшенов теперь отсутствует за ненадобностью, но комбинации пока оставил как объект для возможного дальнейшего расширения функционала. Замечу, что данный подход я использовал со связкой с PolymerJS, а потом с VueJS, и использовал для интеграции с Redux библиотеки polymer-redux и vuedeux соответственно. И так как там бинд на конкретные свойства стейта идут по пути, то меня и миновала проблема мутаций, так как было необязательно мутировоать рутовый стейт при мутировании одного из поддеревьев.
UPD2:
Добавил сборщик rollup для компиляции проекта
Only registered users can participate in poll. Log in, please.
Может ли быть полезным данный подход?
4.41% Да3
7.35% Скорее всего да5
32.35% Нет22
33.82% Скорее всего нет23
10.29% Возможно7
11.76% Не могу ответить8
68 users voted. 29 users abstained.