Skip to content

Instantly share code, notes, and snippets.

@rohozhnikoff
Last active July 12, 2017 11:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rohozhnikoff/f226d7a2004129b74842f5f69c85b920 to your computer and use it in GitHub Desktop.
Save rohozhnikoff/f226d7a2004129b74842f5f69c85b920 to your computer and use it in GitHub Desktop.
// Дэн проводит мысленный переход с одной функции, к разделению на ветки
// http://redux.js.org/docs/basics/Reducers.html
// в ишью на вопрос "хорошо ли использовать комбайн-редюсеры внутри редюсеров"
// https://github.com/reactjs/redux/issues/738, Дэн отвечает утвердительно
// При этом предложенное им решение комбайнРедюсера продолжает оставаться флет, заставляя раскладывать
// схему приложения в один уровень (не давая использовать удобство иерархии),
// а внутренюю оставляя на усмотрение разработчика
// решаемая задача:
// оставить схему сколь угодно глубокой, выставляя редюсеры на более точечном уровне
// сохранить полную совместимость с оригиналом, позволяя заменить "без боли", с ожидаемым поведением
import {createStore, combineReducers} from 'redux';
import isPlainObject from 'lodash/isPlainObject';
// todo: подхачиваем нативный combineReducers на проброс ключа в параметре
// проверка на невалидные редюсеры должна оповещать о полном ключе
// подумать как пробрасывать полный ключ в SanityError редюкса
/** РЕШЕНИЕ В ЛОБ */
export function combineNestedReducers(reducers) {
if(isFunction(reducers)) return reducers;
if (!isPlainObject(reducers)) {
console.error('[combineNestedReducers] error value in schema', reducers);
}
const preparedReducers = Object.keys(reducers).reduce((memo, key) => {
const value = reducers[key];
if (typeof value === 'function') {
memo[key] = value
} else if (isPlainObject(value)) {
memo[key] = combineNestedReducers(value)
} else {
console.error('[combineNestedReducers] error value in deeper schema', {key, value, reducers});
}
return memo
}, {});
return combineReducers(preparedReducers);
}
const store = createStore(
combineNestedReducers({
_function: (state = true, action) => state,
_hash: {
_hash_function1: (state = true, action) => state,
_hash_function2: (state = false, action) => state,
_hash2: {
_hash2_function: () => 123,
}
}
})
);
console.log(JSON.stringify(store.getState(), null, 2));
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
{
_function: true,
_hash: {
_hash_function1: true,
_hash_function2: false,
_hash2: {
_hash2_function: 123
}
}
}
*/
/** продакшн решение */
// решение в лоб все таки добавляет некоторую часть дублирующихся проверок
// переписываем с нуля в похожем с оригиналом стиле
// обучаем все рекурсивному обходу "на месте",
// без глобальной подготовки флет схемы и полного перезапуска на каждом ветвлении
// у ребят интересный "концепт-паттерн" для иммутабла
// конфликтует с ФСА, называют Ветки Доменами
// тоже называют схему схемой, но продлевают ее до ивент хендлеров
// добавляют инициализирующий хендлер через кастомный ивент CONSTRUCT
// https://github.com/gajus/canonical-reducer-composition
// из бонусов - оповещают об неотхендленных ивентах (мы можем только об одинаковом стейте, что не есть ошибка)
// обсуждение: https://github.com/reactjs/redux/issues/2022
// хорошее описание принципа: https://blog.kwintenp.com/combinereducers-enhanced/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment