Мотивация
По мере того как требования к одностраничным JavaScript приложениям становятся все более высокими, мы вынуждены управлять все большим количеством состояний (State) с помощью JavaScript. Эти состояния могут включать в себя ответы сервера, кэшированные данные, а также данные, созданные локально, но еще не сохраненные на сервере. Это также относится к UI-состояниям, таким как активный маршрут (route), выделенный таб, показанный спиннер или нумерация страниц и т.д.
Управлять постоянно изменяющимися состояниями сложно. Если модель может обновить другую модель, то представление может обновить модель, которая обновляет другую модель, а это, в свою очередь, может вызвать обновление другого представления. В какой-то момент вы больше не знаете, что происходит в вашем приложении. Вы больше не можете контролировать когда, почему и как состояние обновилось. Когда система становится непрозрачной и недетерминированной, трудно выявить ошибки или добавлять новую функциональность.
Это достаточно скверно, принимая во внимание новые требования, становящиеся обычными для фронтэнд-разработки, такие как: обработка оптимистичных обновлений (optimistic updates), рендер на сервере, извлечение данных перед выполнением перехода на страницу и так далее. Как frontend-разработчики, мы пытаемся совладать со сложностью, с которой мы никогда не имели дела прежде, и поэтому неизбежно задаемся вопросом: настало время сдаться?
Эта сложность возникает из-за того, что мы смешиваем две концепции, которые очень нелегки для понимания: изменения (mutation) и асинхронность (asynchronicity). Я называю их Ментос и Кола. Обе эти концепции могут быть прекрасными по отдельности, но вместе они превращаются в бардак. Библиотеки, аналогичные React, пытаются решить эту проблему на уровне представления, удаляя асинхронность и прямое манипулирование DOM. Тем не менее, React оставляет управление состоянием данных за вами. И тут в дело вступает Redux.
Идя по следам Flux, CQRS и Event Sourcing, Redux пытается сделать изменения состояния предсказуемыми, путем введения некоторых ограничений на то, как и когда могут произойти обновления. Эти ограничения отражены в трех принципах Redux.