Comments 8
Набор рекомендий довольно странный и даже спорный. Аргументации не хватает, опять же.
Рекомендация не хранить состояние в системе, предназначенной для управления состоянием. Ну, такое. Кроме того - если у нас асинхронный код (загрузка данных) в эффекте, то каким еще образом компоненту узнать о состоянии это загрузки.
Ок
Изменение вложенных объектов - к каким проблемам с отслеживанием изменений это приводит? Мы же, конечно, не говорим про прямую мутацию объектов в стейте (`state.a = newValue`), что нарушает основное правило редьюсера?
Не очень понятно, о чем речь. С примером было бы лучше :)
А что за проблемы с редиректом в эффекте? И где тогда делать редирект?
id
в fetch - звучит как очень специфический рецепт для специфической задачи. Например, в подавляющем большинстве наших задач switchMap в эффекте отлично справляется с отменой, никаких айди не надо.Для SSR надо быть осторожней не только с интервалам, но и таймаутами. И не только в эффектах, а вообще во всем приложении. Ничего redux-специфичного тут нет. А помимо части про SSR, рекомендация звучит как "не использовать интервал, потому что он генерит длинную последовательность событий". Как бы его используют исключильно тогда, когда нам нужно сгенерить такую последовательность. Опять же, неважно эффект это или нет.
Там я скорее про то, что если хранить состояния в стейте, то приходится писать много однотипного кода.
Разберу на примере загрузки.
Происходитdispatch
событияload
. Вreducer
для экшенаload
, свойствоloading
приравниваетсяtrue
, затем если успешно загрузили вызываемloadSuccess
и меняемloading
наfalse
, иначе вызываемloadFailure
и делаемloading
равнымfalse
.
Для того чтобы получить данные из стейта нужно будет создать селекторы. Затем в компоненте подписаться на конкретный селектор.
Все выше описанное можно схлопнуть в одну подписку наloadSuccess$
, гдеloadSuccess$
этоactions.pipe(ofType(loadSuccess))
. И тогда не нужно будет менять reducer, не нужно создавать селекторы.
Конечно, иногда есть смысл хранить состояния в стейте, но в большинстве случаем это избыточно.Хорошо
Я имел ввиду, что конструкции вида
{ ...state, myObject: {...state.myObject, tags: [...state.myObject.tags, ...other]} }
усложняют читабельность и перегружают мутацию. Что не нужно в редьюсере делать сложные вычесления и желательно в редьюсере выполнять только простые операции - заменить объект новым, поменять статус флага.Это когда свойствами
state
являются другиеstate
- { state1: { loading: boolean}, state2: { changing: boolean} }.Проще объяснить на примере. Клиент кликает оплатить товар и после этого, клиента нужно перенаправить на внешний платежный ресурс. Однако клиент не дожидаясь этого уходит на другую страницу. Если редирект сделать в эффекте, то клиент уходя со страницы увидит новую страницу, а потом будет перенаправлен на платежную систему. Если бы редирект был в компоненте, то тогда запрос на перенаправление был бы прерван и клиент уходя из "корзины", дальше бы продолжил свои действия.
Согласен.
Да, возможно я связал две не связанные вещи.
loadSuccess$
- это вы сильно упростили. Все равно же нужно состояние, а не событие (допустим, чтобы показывать/скрывать спиннер в шаблоне). Таким образом, это превратится во что-то типа
public loading: boolean
...
actions$.pipe(
ofType(loadSuccess, loadFailure),
takeUntil(this.onDestroy)
).subscribe(() => {
this.loading = false;
this.changeDetectorRef.markForCheck()
})
Что довольно-таки до фига кода, когда задача была "избавиться от бойлерплейта".
Кроме того, так компонент больше завязан на детали эффекта. Возможно, вам в этом случае вообще не нужен эффект? Фетчим данные прямо из компонента, затем диспатчим результат в стор.
Да, модифицировать вложенные структуры - боль. Я тоже старюсь придерживаться плоского стейта по возможности. Если это частый случай, то что-то вроде https://immerjs.github.io/immer/ должно помочь сделать это более читаемым.
Если речь про вложенные редьюсеры - то почему это плохо? Если же все делается одним редьюсером, то это в копилку предыдущего пункта про вложенные изменения.
Эта же логика справедлива для любых сайд эффектов. не только редиректа, разве нет? Отписываемся, где надо. Согласен, что в случае именно с редиректом эффект для пользоваля более заметен, чем когда мы, скажем, просто продолжаем загружать данные в фоне и запихивать в стор, хотя юзер уже ушел на другую страницу.
Я вообще миновал стадию с использованием классического redux/ngxs/ngrx увидев в соседнем проекте во что это превратилось спустя год. Сказал ну его нафиг и взял акиту чтобы просто иметь четкую точку истины и этого вполне хватило + разработчиков обучать не надо было раскапывать портянку нечитаемого rxjs кода.
Сейчас в новых проектах в основном использую elf, потому что даже бойлеплейт акиты стал надоедать, но думаю уже над тем чтобы и от него отказаться.
Redux в Angular. Туда и обратно