habrahabr

5 причин, почему вы должны забыть о Redux в приложениях на React

  • суббота, 13 июля 2019 г. в 00:19:50
https://habr.com/ru/post/459706/
  • Разработка веб-сайтов
  • JavaScript
  • ReactJS


Я работаю с Реактом на протяжении почти 3 лет, использовал как Redux так и MobX и у меня к текущему моменту возник вопрос. Почему абсолютное большинство front-end разработчиков продолжают свято верить в то, что Redux + Redux Saga + Reselect + 100500 других библиотек «облегчающих» жизнь — это лучшее решение на сегодняшний момент? Я приведу 4 аргумента в пользу того, чтобы в следующем проекте вы использовали MobX вместо Redux.

MobX позволяет писать более чистый и понятный код


Давайте сраним 2 фрагмента кода, которые делают тоже самое. Вот как выглядит редюсер в Redux:

image

Чтобы изменить состояние, вам нужно вызвать функцию, которая называется action в терминологии Редакс:

image

И в большинстве случаев (не всегда, но это «лучшие практики» которые используются на многих проектах) вам надо будет написать вот такой boilerplate:

image

Потом надо будет инициализировать store (это надо будет сделать один раз, но всё же):

image

И прокинуть наш заинициализированный стор дальше в приложение через провайдер (тоже одноразовая операция):

image

Теперь можно выполнять какие-то операции с данными в ваших компонентах:

image

Получается, что в случае с Redux, чтобы поменять данные в вашем хранилище, вы должны вызывать какие-то функции, которые будут создавать новый объект состояния… Лично по мне, это звучит как полная ерунда. Давайте глянем на тот же фунционал в исполнении MobX. Наш стор:

image

И дальше можно использовать в компоненте:

image

Да, всё верно, вместо каких-то функций, которые изменяют объекты, вы можете использовать классический ООП подход, с классами, их свойствами и методами. Пусть вас не пугают декораторы(@) внутри, они просто добавляют функционал, необходимый для отслеживания изменения данных. Кстати, похожий подход, с классами, для хранения данных используется в Angularjs (Скрин взят отсюда angular.io/start/data):

image

MobX позволяет писать меньше кода


Чтобы убедиться в этом просто посмотрите на примеры выше. И теперь, вместо написания бесконечного бойлерплейта, можно наконец-то сосредоточиться на написании бизнес логики приложения, что не может не радовать.

Третье — оптимизация производительности


Если посмотреть примеры выше, то можно увидеть, что в случае с MobX я не использовал pure component и это не ошибка. Вам просто не надо использовать никакую оптимизацию в этом случае, потому что ваш компонент будет перерендериваться только тогда, когда данные, которые вы в нем используете поменяются. И да, можно забыть о Pure Components, shouldComponentUpdate и что вы там ещё используете в этих случаях. В идеале, каждый ваш компонент, который не HOC и использует какие то данные из хранилища должен быть observable и тогда вы забудете о проблемах с оптимизацией навсегда.

Четвертое — меньше зависимостей


Тот кто использует Redux, должен не по наслышке знать, что в комплекте с ним идет множество «замечательных» билиотек. И хорошо, если это будет просто thunk, а может быть и так, разработчики пойдут по пути света тьмы и захотят использовать Redux Saga, Reslect и еще кучу непонятных библиотек, которые делают ваш код не только более медленным, но и более сложным в понимании. И допилить какой-то незначительный функционал или найти баг в этом произведении будет невероятно сложно и долго. MobX это ultimate решение == не требующее дополнительных библиотек, лишит вас всех этих прелестей, поэтому с ним бизнес логика вашего приложения будет чистой, как слеза младенца.

UPD. Спасибо MaZaAa

Пятая причина — возможность отказаться от setState


setState несёт в себе ряд недостатков (краткий перевод статьи которую можно в оригинале прочитать тут):

1. Он асинхронный.


Это может привести к неожидаемому поведению:

image

На скрине выше в алерте должно было быть 2, но так как setState асинхронный, он приходит позже.

2. setState ведет к ненужным перерендерам компонента:


а. Он перерендеривается, даже если новое значение == старому значению
б. Есть ситуации, когда изменение state не приведет ни к какому изменению, например, когда у нас есть условия для отбражения в котором стоит state. На скрине ниже при клике произошел перерендер, хотя данные не должны рендериться из-за условия fasle:

image

в. Иногда данные, которые обновляет setState вообще не играют роли в отрисовке DOM (например, таймеры). И всё равно происходит перерендер компонента.

3. setState подходит далеко не для всех случаев.


Есть компоненты, в которых используются хуки / методы жизенных циклов компонента и в этом случае будет не только происходить лишний перерендер, но эти события (хуки) будут вызываться каждый раз при этом, что может привести к странному поведению.

Использование MobX оградит вас от этих недостатков, ведь можно полностью отказаться от setState:

image

Если вы с чем-то не согласны или я чего-то не понимаю приводите контраргументы в комментариях. Ссылка на сэндбокс из которого взяты скрины с MobX: codesandbox.io/s/mobxreact-s7db5, c Redux: codesandbox.io/s/oj7px08qy9