- PVSM.RU - https://www.pvsm.ru -

Redux store: Расширение по «горизонтали»

Redux Когда приложение, использующее Redux [1], разрастается до достаточно больших размеров, количество состояний увеличивается многократно. Для разделения редьюсеров на логические единицы применяется подход комбинирования их с помощью combineReducers [2]. Данное решение позволяет расширить store [3] по «вертикали». Но бывают случаи, когда данного разделения может быть недостаточно. Например, один из уровней несет в себе составную логику, которую тоже было бы неплохо разделить (или как говорил один из известных людей: «Ухлубить!»). Но такого подхода нет в API Redux. И поиск решения данного вопроса так же ничего не дал (может плохо искал). Поэтому я разработал свой подход расширения по «горизонтали» Redux Store.

Хочу Вас ознакомить со своим проектом [4], который позволяет осуществить данный подход.

Использование

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,
		actions: [
			actionsTypes1,
                        ...
                        actionsTypesN
		]
	}
};

где мы задаем название будущего раздела 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) {
  ...
  combine(...arguments);
  ...
  return state;
};

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,
		actions: [
			actionsTypes11,
                        ...
                        actionsTypes1N
		]
	},
        ...
        <name propN>: {
		module: level2ModuleN,
		actions: [
			actionsTypes1N,
                        ...
                        actionsTypesNN
		]
	}
};

и по «горизонтали», за счет использования описанного выше подхода на каждом из 2+ уровней.

Исходники [4]

Автор: kolesoffac

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/262373

Ссылки в тексте:

[1] Redux: http://redux.js.org/

[2] combineReducers: http://redux.js.org/docs/api/combineReducers.html#combinereducersreducers

[3] store: http://redux.js.org/docs/basics/Store.html

[4] своим проектом: https://github.com/kolesoffac/redux-combine-deep-props

[5] Источник: https://habrahabr.ru/post/335868/