Comments 15
Расскажите, чем ваш подход лучше использования вложенных combineReducers (https://github.com/reactjs/redux/issues/738) вместе с reduce-reducers от Эндрю Кларка?
+1
Как я понял — это теоретическое рассуждение на тему. Без практической реализации. Я предоставил практический подход к решению данной задачи.
-1
Да нет, вот вам практическая реализация(из issue по ссылке) которая вообщем-то должна работать прекрасно:
rootReducer = combineReducers({
router, // redux-react-router reducer
account: combineReducers({
profile: combineReducers({
info, // reducer function
credentials // reducer function
}),
billing // reducer function
}),
// ... other combineReducers
})
});
+1
В такой архитектуре все пропертис — это обязательно должна быть функция-редьюсер.
В моем подходе в раздел «profile», например, проперти «isUse». И я бы не смог этого сделать — пришлось бы запихивать его в один из разделов «info» или «credentials», или вообще создавать новый. Все это привело бы к ненужной избыточности иерархии. Мой подход, считаю, более гибкий в этом отношении.
В моем подходе в раздел «profile», например, проперти «isUse». И я бы не смог этого сделать — пришлось бы запихивать его в один из разделов «info» или «credentials», или вообще создавать новый. Все это привело бы к ненужной избыточности иерархии. Мой подход, считаю, более гибкий в этом отношении.
-1
Вы хотите вот такую структуру в ветке стейта?
Хозяин — барин. Обсуждение, зачем именно это понадобилось — непродуктивно. Но если я правильно вас понял, то вот простой пример решения:
Конечно же isUsed — это просто чистая функция, как и любой редьюсер, и вы можете делать с ней всё, что захотите. Например в привычном виде (у вас в примерах это switch, у меня — createReducer) сделать обработку по нужным actionTypes, а вместо spread-оператора использовать Ramda, Immutable и так далее. Не придумывая дополнительные соглашения по нотации «объекта комбинаций».
profile: {
info: Object,
credentials: Object,
isUsed: boolean,
}
Хозяин — барин. Обсуждение, зачем именно это понадобилось — непродуктивно. Но если я правильно вас понял, то вот простой пример решения:
const isProfileUsed = state => ({ ...state, isUsed: true });
const profileParams = combineReducers({
info,
credentials,
});
const rootReducer = combineReducers({
router,
account: combineReducers({
profile: reduceReducers(profileParams, isProfileUsed)
billing,
}),
// ... other combineReducers
});
Конечно же isUsed — это просто чистая функция, как и любой редьюсер, и вы можете делать с ней всё, что захотите. Например в привычном виде (у вас в примерах это switch, у меня — createReducer) сделать обработку по нужным actionTypes, а вместо spread-оператора использовать Ramda, Immutable и так далее. Не придумывая дополнительные соглашения по нотации «объекта комбинаций».
0
Это еще один подход к решению подобной задачи, но вы здесь используете reduce-reducers, то есть не решаете задачу родным API. Поэтому отличие только в реализации. На панацею не претендую, но думаю мой подход кому-нибудь может быть полезен.
0
Конечно, может быть полезен :) Просто мы обсуждали решение проблемы более «проторенным» путём. Как видите, такой путь есть. Возможно поэтому в опросе подавляющее большинство голосов «нет» и «скорее всего нет»?
Насчёт родного API: redux не даёт такого апи вообще. Всё, что есть — это набор соглашений и полная свобода делать что угодно с корневым редьюсером (кто во что горазд — как было с классическим Flux до появления Redux, который стал стандартом де-факто). CombineReducers был введён лишь чтобы дать похожую на классический Flux возможность разделения общего стейта на отдельные «домены». И в работе с составной логикой в редьюсерах тоже есть стандарт де-факто: обычный функциональный подход.
Btw, у вас могут быть проблемы с мутацией стейта.
Насчёт родного API: redux не даёт такого апи вообще. Всё, что есть — это набор соглашений и полная свобода делать что угодно с корневым редьюсером (кто во что горазд — как было с классическим Flux до появления Redux, который стал стандартом де-факто). CombineReducers был введён лишь чтобы дать похожую на классический Flux возможность разделения общего стейта на отдельные «домены». И в работе с составной логикой в редьюсерах тоже есть стандарт де-факто: обычный функциональный подход.
Btw, у вас могут быть проблемы с мутацией стейта.
0
UFO just landed and posted this here
Почему вы решили, что reduceReducers «раскомбинирует» в плоскую структуру? Это же обычный функциональный fold всех редьюсеров. В моём примере никакого раскомбинирования в плоскую структуру не происходит, это просто slice reducer, который отвечает не за ветки info и credentials, а за весь их родительский узел profile.
А зачем так делать — спросите у автора. Я лишь предложил более простой (по моему скромному мнению) вариант решения проблемы, который проще, чем предложенный автором. Тоже считаю, что где-то тут у автора неправильно сформирована структура данных.
А зачем так делать — спросите у автора. Я лишь предложил более простой (по моему скромному мнению) вариант решения проблемы, который проще, чем предложенный автором. Тоже считаю, что где-то тут у автора неправильно сформирована структура данных.
0
Например, один из уровней несет в себе составную логику, которую тоже было бы неплохо разделить (или как говорил один из известных людей: «Ухлубить!»). Но такого подхода нет в API Redux.
Углубление ни к чему хорошему не приведет. Во-первых вложенное дерево намного сложнее поддерживать, усложняется логика редьюсеров, во-вторых усложняется логика селекторов, что может вылезти неприятными сюрпризами при рефакторинге, в-третьих это может повлиять на производительность (у меня в одном проекте даже redux-devtools через раз открывался).
Изначально, при знакомстве с редаксом, у меня возникла идея обернуть в combineReducers все ветки, чтобы можно было передавать только схему стора, но попробовав на практике решил использовать наиболее плоскую структуру.
+1
А Вы пробовали на практике эту схему с приложенным кодом? combineReducers — не для этого.
Вложенные структуры оправдывают себя при разведении логики по отдельным файлам, а не писать все редьюсеры кучей в руте. И данный могут хранится в нормализованном виде. Данные никакого отношения не несут на структуру обращения к ним. Я использовал redux со связкой с polymerjs, а сейчас с vue и там я биндю стор через путь, что не несет за собой никакой нагрузки. А вот когда происходит оперирование со сложной иерархической структурой в редьюсере, согласен, что при большом размере структуры могут быть задержки выполнения, но это на себя берет lodash. И это уже дела оптимизации, необязательно же уходить сильно далеко вглубь, и не обязательно хранить большие объемы данных, можно периодически скидывать кэш(в редаксе есть для этого расширения). Но в целом задача по разделению логики решена, причем в достаточно автоматическом режиме: в каждом редьюсере работаете как в руте, и один только раз описывайте комбинации, остальное дело техники.
Вложенные структуры оправдывают себя при разведении логики по отдельным файлам, а не писать все редьюсеры кучей в руте. И данный могут хранится в нормализованном виде. Данные никакого отношения не несут на структуру обращения к ним. Я использовал redux со связкой с polymerjs, а сейчас с vue и там я биндю стор через путь, что не несет за собой никакой нагрузки. А вот когда происходит оперирование со сложной иерархической структурой в редьюсере, согласен, что при большом размере структуры могут быть задержки выполнения, но это на себя берет lodash. И это уже дела оптимизации, необязательно же уходить сильно далеко вглубь, и не обязательно хранить большие объемы данных, можно периодически скидывать кэш(в редаксе есть для этого расширения). Но в целом задача по разделению логики решена, причем в достаточно автоматическом режиме: в каждом редьюсере работаете как в руте, и один только раз описывайте комбинации, остальное дело техники.
-1
Документация Redux как раз и предлагает не писать все редьюсеры кучей в руте. Более того, прямым тестом сказано, что combineReducers — просто пример, что каждый может сам себе режиссёр реализовать свой вариант combineReducers. Так что формально ваше предложение не нарушает заветы авторов Redux.
Но для декомпозиции редьюсеров обычно используют функциональный подход, и это оказывается намного удобнее. А для работы с вложенным деревом — нормализацию стейта.
Но для декомпозиции редьюсеров обычно используют функциональный подход, и это оказывается намного удобнее. А для работы с вложенным деревом — нормализацию стейта.
0
Я ведь не спорю что есть способы добиться того же, например. Но я преследовал цели гибкости и автоматизма и нормализации логики по слоям(разделам) стора.
0
Добавил сборщик для компиляции проекта
0
Sign up to leave a comment.
Redux store: Расширение по «горизонтали»