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

Я работаю с Реактом на протяжении почти 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
Поделиться публикацией

Комментарии 324

    +11
    Мы в своё время в Медиасервисах Яндекса перевели два приложения с Redux на MobX — скорость разработки увеличилась раза в три. Сейчас делаем тоже самое в UBS. Вообще в официальной документации Redux когда-то было написано, что он подходит для примерно 10% приложений. При этом компания-автор, Facebook, в это число не входит. Но хайп же важнее логики, как обычно.
      +13

      А хотите ещё в 3 раза увеличить скорость разработки — выпиливайте React :-)

        +1
        Тогда давай отказываться и от типизации, стандартов, соглашений и многого другого, что занимает время.
        Когда попадаются проекты, на том же реакте, где был сделан упор на скорость, где не используется redux и другие библиотеки получается что то вот такое: github.com/magickasoft/wacdaq/blob/master/src/components/pagesRouter/pagesRouter.jsx

        поэтому иногда эта «шаблонность» и «стандарты» принятые обществом лучше придерживать, так легче вникнуть в проект и дальше развивать проект.
          0

          Ух ты. Спасибо за ссылку. Такое надо в закладки.

            +3
            Вчера проходил собеседование, типичная ситуация, проект полу дохлый:
            1. Плохая структура проекта, все сложено в папку components, нет разделение на компоненты и контейнеры, тяжело разобраться, какая страница отображает какие компоненты, полный хаос

            2. Вся логика в роутере, он же и есть данные + бизнес логика приложения, как это поддерживать?

            3. Полная загрузка страницы занимает около 40 секунд, при этом ресурсов загружается на 20мб, это очень много

            Можно продолжать сколько угодно, больше всего удивляет, что при найме на работу вопросы и тестовые задачи не соответствуют тому, над чем придется работать.
              0

              Классика жанра) к сожалению

            0

            Реакт имеет архитектуру вида — перезапускаем рендер всего приложения и где только можно срезаем углы, чтобы это не тормозило. МобХ же отслеживает зависимости между состояниями и точечно их обновляет. Реакт для МобХ — как собаке пятая нога. А если хочется JSX, то кастомный реактивный рендерер займёт всего несколько сотен строк.

              +2

              Я как-то пытался так и сделать, в итоге все равно Реакт получился. Проблема в самом JSX: если у нас по условию есть функция вида () => JsxFragment, то мы обязаны отслеживать любые ее зависимости и выполнять повторные рендеры с реконциляцией при их обновлениях.


              Можно, конечно, придумать решения для биндинга выражений на свойства, и это будет куда оптимальнее… вот только одно случайно допущенное обращение к observable — и мы снова перед выбором, оставить программу глючить или сделать повторный рендер с реконциляцией как в Реакте.

                0

                Не очень понял вашу проблему, но вместо JsxFragment лучше возвращать DOMElement. Поскольку он каждый раз будет возвращаться один и тот же — инвалидация выше по дереву идти не будет.

                  0

                  А не получится его каждый раз один и тот же возвращать.


                  Только не начинайте снова про "просто добавим уникальный id каждому тегу". Это не защищено от дурака и от глупых опечаток, и просто неудобно.

                    –2

                    Просто наберитесь опыта в реакте и такие вопросы, проблемы и желания у вас врятли вновь появятся

                      0

                      От опечаток защитить не сложно.
                      И наличие человекопонятного идентификатора у каждого элемента — это дико удобно, на самом деле. У них просто тьма полезных применений.

                        +2

                        Как гарантировать уникальность и читаемость одновременно?

                          –1

                          Алгоритм примерно такой:


                          1. При старте рендеринга в глобальные переменные запоминается текущий guid и пустое множество для локальных имён.
                          2. Для каждого тега проверяется есть ли указанный в пропсах id. И если есть, то кидается ошибка.
                          3. guid из глобальной переменной склеивается с локальным id — получается guid для конкретного тега.
                          4. Если в доме есть элемент с аттрибутом id = guid, то берётся он, иначе создаётся новый и ему проставляется этот аттрибут.
                            –1

                            То есть только в рантайме и только когда дойдёт очередь до конкретного рендеринга? Причём где допущена ошибка понятно не будет, выскочить на том компоненте, который рендерится вторым по флоу приложения, а не на том, который был создан вторым по флоу разработки?

                              0

                              Если у вас есть решение лучше — я весь во внимании.

                              0

                              Как-то я не понятно алгоритм объяснил. Лучше глянуть код: https://github.com/eigenmethod/mol/tree/master/dom/jsx

                0

                Скажите, а как? Я ни разу не фронтендер (ладно, я был джуном, но завязал), потребовалось тут сваять что-то не очень сложное, но весьма интерактивное. Наткнулся на эту статью как раз в поисках того, на чем пилить. Если вы советуете выпилить реакт — я с радостью приму ваши советы. Надеюсь, это не jquery, ибо портянки.

                  –6

                  Советую вам изучить HTML5 и пользоваться MDN как библией. А потом уже решать что на чем писать.

                    0

                    HTML, CSS и даже JS я и так знаю. Но писать все на pure js: обработчиках onclick ручном добавлении/удалении тегов нет никакого желания.

                      –8

                      А зачем вам тогда что то изучать, раз вы и так все знаете

                    –4
                      +3

                      Я хочу это развидеть)

                –3

                А как вы делаете серверсайд рендер без наличия общего слепка состояния приложения, которое позволяет делать подход в случае с редаксом?

                  +4
                  Не нахожу зависимости между SSR и redux. Возможно redux+SSR просто описан в документации. Общий стор можно реализовать хоть бы и MobX А можно вообще заюзать graphql+apollo и забыть про стор.
                    0

                    Вы делали SSR на MobX?

                      0
                      Делал на riotjs + effectorjs см. habr.com/ru/post/456448
                      Кстати делал на основе другого проекта reactjs + redux выпиливанием 2/3 кода стора. Перед тем как взял в работу effectorjs процентов 10 сделал на mobx. Конечно у riotjs более открый интерфейс в то время как в react даже redux ходил по недокументированная ранее api.
                        +1

                        Собственно, мой вопрос заключается в следующем: для полноценного SSR необходимо грузить стейт на сервере, рендерить страницу, а потом стейт сериализировать в страницу (в тег script обычно).


                        Судя по архитектуре MobX, в котором модели являются классами, моделям требуется специальный сериализатор.


                        Поддерживают ли модели MobX сериализацию?

                          0
                          Да об этом я не подумал у effectorjs есть из коробки у mobx сложнее но в доках есть описание mobx.js.org/refguide/tojson.html с сериализацией все вроде бы просто а вот десериал щация идёт в отдельном проекте
                            +2

                            Это зачем такие извращения? Сср нужен лишь для роботов, что не умеют в яваскрипт.

                              0
                              Это вопрос с запутанной историей. Ява скрипт умеет скорее всего только google во всяком случае в больших обьемах. Там не менее в доках инфа об этом ограничивалась ответом в интервью одного из сотрудников google, который ответил на вопрос примерно так: можем ли мы парсить яваскрипт? а почему бы и нет?
                              Потом где то год назад появились гайды для веб разработчиков где была показана схема с prerender. То есть как бы подтверждение того что читать они могут но скорее всего не хватало мощностей чтобы делать это для всех сайтов без исключения. И вот теперь недавно появилась серия интервью почему то с распитием коньяка где пропагандируется отказ от ssr и prerender. Я честно говоря воспринял это как то что google теперь гарантированно и 100% читает яваскрипт и решил наконец окончательно стать единственной поисковой системой тк другим для чтения яваскрипт придется на два порядка увеличить мощности по железу что не все поисковики выдержат финансово.
                              Но пока ещё пользователи ищут не только на google. Кроме этого яваскрипт может быть тяжел для работы на слабых девайсах и не читаться скринридерами.

                              Хотя я сталкиваюсь с игнорированием этих вопросов разработчиками. т.к. хочу ангуляр/реакт/вью и не хочу ничего больше знать и ни о чем больше думать.
                                0
                                Кроме этого яваскрипт может быть тяжел для работы на слабых девайсах и не читаться скринридерами.

                                Скринридеры читают то, что отрендерит браузер. Не их обязанность выполнять скрипты.

                              +1
                              Там в комментариях ниже рекомендуют для этого использовать mobx-state-tree
                          0

                          А есть примеры использования graphql + Apollo вместо redux или стора в принципе?

                          +1

                          Идея с единым местом, хранящим всё состояние приложения, очень помогает при разработке изоморфных приложений. На mobx можно сделать подобное, с помощью mobx-state-tree, который здесь уже посоветовали, но тогда вы получаете почти тот же самый редакс.

                            0

                            При чем тут state-tree? Просто mobx тебе позволяет делать единое место хранения и ещё много всего, никак не ограничивая тебя и не связывая руки.

                              +1

                              Ок, а можно статью на эту тему, или пример кода, где это единое состояние хранилища генерируется на сервере, далее передаётся на фронтенд, чтобы первичная его инициализация произошла с уже с сгенерированными сервером данными, и тот хтмл, который отрендерился сервером, не приходилось рендерить повторно на клиенте и не приходилось повторно подгружать данные с бекенда, необходимые для этой страницы? Собственно, что и является полноценной реализацией изоморфного приложения. На mobx, конечно же.

                                0

                                Я напишу статью когда вернусь из отпуска, с телефона это будет сделать нереально. А вообще я писал уже комментарий по этому поводу с подсказками, что надо сделать чтобы работало так, как вы хотите. Можете его прочитать и ветку с этим комментарием и может у вас все встанет на свои места если уже юзали mobx

                          0
                          А как вы делаете серверсайд рендер без наличия общего слепка состояния приложения, которое позволяет делать подход в случае с редаксом?

                          А какой вам при SSR нужен стейт кроме, с-но, самого роута?

                            0

                            Данные которые дёргаются от АПИ, что бы отрендерить например страницу со списком товаров

                              0
                              Данные которые дёргаются от АПИ, что бы отрендерить например страницу со списком товаров

                              Ну так дергаете и рендерите, в чем там проблема и как с ней связано mobx/redux?

                              0
                              Имеется в виду не только ssr а так называемые универсальные или изоморфные веб приложения. Там только первая страница рендерится на сервере и есть процесс гидратации когда на клиенте воссоздаются компонкнт с тем же состоянием. То есть если на клиенте для управлением состояния используется стор то он же должен быть заюзан и на сервкрк
                                0
                                То есть если на клиенте для управлением состояния используется стор то он же должен быть заюзан и на сервкрк

                                Не понял, зачем? состояние в роуте, с-но просто рендерим с роута, как обычно. Где проблема возникает?

                                  0
                                  Код должен быть единым на клиенте и на сервере. Если я перейду на страницу с категориями товаров то скорее на клиенте будет вызван метод например getCategiries который загрузит с сервера данные в стор и у меня на странице появится списков категорий. Теперь я нажимаю клавишу F5 и загружаю страницу с сервера. На сервере чтобы мой компонент отрендерился с категориями нужно инициализировать стор со списком категорий. Тк это тот же самый компонент который работал и на клиенте.
                                  Если реакт использовать для чисто серверного рендеринга где все страницы рендерится на сервере то сторинеинужен
                                    +1

                                    А так ли нужен этот серверный рендеринг?

                                      0

                                      Только если seo оптимизация критична, у меня тьфу тьфу таких проектов на реакте не было и не будет (обычно это интернет магазины и прочее не интересеое)

                                        0

                                        Я вам по секрету скажу что для роботов можно выдавать HTML без JS, а для человеков JS без HTML. И нет, вас не забанят поисковики — можете погуглить их рекомендации по индексированию js-приложений.

                                      +1
                                      Теперь я нажимаю клавишу F5 и загружаю страницу с сервера.

                                      Ну и пусть так же вызывается getCategiries и грузит данные. Не понимаю, в чем проблема возникает. Код-то один и тот же.

                                        0
                                        На клиенте getCategiries грузит данные в стор. Если функцию вызвать на сервере она также сделает то же самое что и на клиенте то есть загрузит данные в стор. Стор передается на сервере компоненту для его серверного рендеринга. После этого стор должен быть скриализован и отправлен на клиент чтобы на клиенте повторно не вызывать метод getCategories. На клиенте стор десериализуктся и передается в компонент при его гидратации (hydrate())
                                        Проблема которая послужила началом этого треда состояла в том что mobx не имеет встроенного метода для десериализации объекта и как я понял по коду примеров с сериализацией там тоже не все хорошо в части циклических обьектов
                                          +1

                                          Можно просто написать свое решение и все, там на самом деле все достаточно просто, подсказка: сериализатор и десириализатор + функция которая будет вызываться в конструкторе каждого класса mobx которая будет восстанавливать его состояние и будет счастье с минимальным вмешательством в архитектуру и в целом в код

                                        +3
                                        Если реакт использовать для чисто серверного рендеринга где все страницы рендерится на сервере

                                        Тогда и реакт не нужен
                                          +1
                                          Тогда нужен серверный шаблонизатор. Которые непонятно, чем лучше. При этому хорошо понятно, чем хуже — поддержки типов в них не завезли, по-крайней мере в нодовские.
                                            0

                                            А вот в том же Razor (asp.net) есть не только поддержка типов — но и поддержка метамодели, которая позволяет провести как клиентскую валидацию, так и серверную, на основе атрибутов (=аннотаций) свойств.


                                            И для простых CRUD эту же валидацию можно частично продублировать на стороне СУБД средствами Entity Framework.

                                              0
                                              В Play — тоже, но даже для Java это редкое поведение
                                        0
                                        То что написал apapacy и есть то, что подразумевается под «react ssr». Первый запрос рендерится с сервера, всё остальное уже на клиенте. В данном случае, необходимо иметь полный отпечаток состояния приложения независимо от того, выполняется код нодой или браузером.
                                  +3
                                  При этом компания-автор, Facebook, в это число не входит.

                                  Facebook и не была автором Redux.

                                  –4
                                  Согласен, много шаблонного кода, но если использовать redux-act все становится немного удобнее и к тому же, где находится логика приложения? Вместе с данными? Мне больше нравится использовать Redux-Saga, данные отдельно, логика отдельно.
                                    0

                                    Вообще как удобно так и можешь делать, никаких ограничений и навязывания что и как надо делать

                                      +5
                                      Логику можно разделить на логику отображения и логику обработки данных. Логику отображения храните в компонентах React, логику обработки данных вместе с данными, которые эта логика обрабатывает. Никаких минусов такого подхода за долгие годы не обнаружил, наоборот фичи получаются более локализованные.
                                        0
                                        Согласен, такой подход позволяет убрать всю бизнес логику из компонентов, оставить в них только логику отображения. Тут тоже несколько плюсов:
                                        1. Компоненты становятся меньше и соответственно более понятно, что в них происходит
                                        2. Если в компонентах фигачить бизнес-логику, она будет пересчитываться каждый раз, когда этот компонент будет перерендериваться, а это минус к производительности
                                        3. Компоненты становятся менее зависимыми от данных == больше шанс их переиспользовать.
                                        –1
                                        Можно создать отдельный класс в котором будут данные и отдельный класс в котором будут методы. Лично я предпочитаю хранить и данные и методы для этих данных в одном классе:
                                        class Users {
                                           @observable list = [];
                                           @action getUser = (id) =>{
                                               return this.usersList.filter(user => return {user.id == id})
                                           }
                                           @action fetchList = () => {
                                               return new Promise((resolve, reject) => 
                                                        api.get('someUrl')
                                                            .then(res=> {
                                                                  this.list = res.data;
                                                                  resolve()
                                                             })
                                                           .catch(e => reject(e))
                                               )
                                           }
                                        }
                                        

                                        Такой подход позволяет не просто хранить данные, а создавать сущности и потом в компоненте сразу понятно, что происходит:
                                        try {
                                            await Users.fetchList();
                                            Users.getUser(id);
                                        } catch(e){
                                            console.log(e)
                                        }
                                        
                                          0
                                          Я вот не сторонник объединения разных обязанностей в одном классе.
                                          Для меня норм, когда стор хранит данные и отвечает за их преобразование при обращении к нему. На мой взгляд, не стоит совмещать в сторе работу с данными и отправку запросов на сервер.
                                            0

                                            Единого правильного пути нет, кому как удобнее и кто как считает более приемлемым

                                              +1
                                              Недавно попал на поддержку проект абсолютно правильный. И это тоже иногда бывает не то что бы плохо а неудобно. Например обычный restapi put user. Тут и в роуте можно сохраниться в базу данных и забыть. Но это слишком просто. В роуте мы вызываем контроллер saveUser. ОК тут бы и остановиться. Но нет из контроллера мы вызываем сервис saveUser. Классно уже кажется хватит. Но нет из сервиса мы делаем метод репозитория saveUser. И тут уж — опять нет мы идём в прослойку между базой и всем что было до того которая почему то называется DTO. И здесь то у мы наконец сохраняемая.

                                              Вроде бы и не поспоришь. А начнёшь спорить то будешь уличен в нарушении SOLID. Но как то все это подозрительно из простой задачи превратилось в какие то джунгли
                                                +1

                                                Как я тебя понимаю, к великому сожалению такая жесть преобладает

                                                  +4
                                                  А начнёшь спорить то будешь уличен в нарушении SOLID.

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

                                                  Чем плоха разнородность? Новый человек потом на проекте будет долго искать куда подставить свой код. Потому что вчера он делал тот же функционал логирования метрики и правил что-то в контроллере модуля, а у этого модуля контроллера нет, ну зато репозиторий есть, поставлю там, в данный момент все тоже самое. Потом контроллер появится и логгирование метрики станет работать некорректно.

                                                  Поэтому зачастую проще сразу накидать стандартную структуру содержащую все возможные этапы обработки запроса/жизненного цикла или чего-то еще, чем потом на ходу пытаться их выделить.

                                                  Возможно Вы думаете, что большинство таких контроллеров/сервисов/репозиториев — не занятых ничем кроме проброса значения дальше, это какое-то отражение внутренней логики. Нет, это тупо форматирование. Как скобочки — форматирование для файла, так и эти тривиальные классы — форматирование для проекта. Возможно ху… е, возможно стоило сделать нормальное дефолтное поведение, но главно это одинаковое на всем проекте.
                                                    +1

                                                    Главное, чтобы реально было одинаково, чтобы каждый чётко понимал ответственность каждого слоя.

                                                  +2
                                                  Когда я в 2012м увидил такой подход в Backbone, он у меня тоже вызвал протест. Но на практике оказалось, что связывать серверные данные и методы работы с сервером не такая плохая идея. Возможно потому что часто между ними есть логическая сильная связанность, и это прощает повторение этой связанности в коде. Но это не определяет использование ни MobX, ни Redux, ни чего-либо ещё. Просто Redux физически не позволяет так сделать, а MobX оставляет выбор за вами. Разделять или объединять (DDD или CQRS) — зависит от природы данных, требований и слишком многих других факторов.
                                                  0

                                                  Лучше так, как вы написали, не делать...


                                                  Во-первых, при наличии таких операций как getUser, элементы хранить надо в Map, а не в массиве. При использовании MobX это особенно важно, ведь от структуры данных зависит какие будут подписки: к примеру, сейчас у вас каждый вызов getUser подписывается на нулевой элемент массива.


                                                  Во-вторых, если fetchList — единственная мутирующая операция, то имеет смысл использовать observable.ref вместо observable.


                                                  В-третьих, откуда вы взяли этот паттерн с оборачиванием Promise в другой Promise?! Зачем вообще внешний Promise нужен?


                                                  В-четвертых, action не действует на асинхронные продолжения. Конкретно в приведенном вами коде декоратор action бессмысленный.

                                                    –2
                                                    Во-первых, при наличии таких операций как getUser, элементы хранить надо в Map, а не в массиве.

                                                    Не монимаю, почему в данном примере надо использовать map. Я этот массив не собираюсь никак менять.

                                                    Во-вторых, если fetchList — единственная мутирующая операция, то имеет смысл использовать observable.ref вместо observable.

                                                    С этим согласен

                                                    В-третьих, откуда вы взяли этот паттерн с оборачиванием Promise в другой Promise?! Зачем вообще внешний Promise нужен?


                                                    Конкретно в данном случае это не нужно, писал в спешке. Такую конструкцию Promise в Promise, я обычно использую когда неизвестно, какой статус от сервера может придти. Это может быть 200 или 400. И то и то нормально. Но если я потом буду ждать ответ в async он упадет, а в случае с двумя промисами у меня есть возможность прописать resolve даже если промис вернется не со статусом ОК.

                                                    В-четвертых, action не действует на асинхронные продолжения. Конкретно в приведенном вами коде декоратор action бессмысленный.


                                                    Оф документация:

                                                    The action wrapper / decorator only affects the currently running function, not functions that are scheduled (but not invoked) by the current function! This means that if you have a setTimeout, promise.then or async construction, and in that callback some more state is changed, those callbacks should be wrapped in action as well!

                                                      +1
                                                      Не монимаю, почему в данном примере надо использовать map. Я этот массив не собираюсь никак менять.

                                                      Вопрос в операции поиска. Посмотрите внимательнее сколько зависимостей создает операция filter...


                                                      Но если я потом буду ждать ответ в async он упадет, а в случае с двумя промисами у меня есть возможность прописать resolve даже если промис вернется не со статусом ОК.

                                                      Но вы можете просто вернуть значение из catch, с аналогичным эффектом.


                                                      Оборачивание промиса в промис не требуется никогда.


                                                      The action wrapper / decorator only affects the currently running function, not functions that are scheduled (but not invoked) by the current function! This means that if you have a setTimeout, promise.then or async construction, and in that callback some more state is changed, those callbacks should be wrapped in action as well!

                                                      Ага, а вы этого (those callbacks should be wrapped in action) не сделали.

                                                +8

                                                Юзаю MobX с 2017 года, после Redux и его "друзей" это просто идеально, да и вообще это серебряная пуля в связке с реактом решает 101% всех задач быстро, эффективно и главное код сохраняет читаемость по мере роста и развития проекта. А ещё шикарнейшая плюшка — он позволяет забыть о this.setState для внутреннего состояния компонента

                                                  –4
                                                  Вся асинхронная логика может реализоваться на чистом Redux через разные уровни Middleware.

                                                  MobX также увеличивает кривую обучения через Observables, которые так и не стали частью языка.

                                                  На своем пути к минимализму я остановился на связке useReducer() hook + Context, которые идут «из коробки» и успешно заменяют мне 90% функциональности Redux.
                                                    +4

                                                    Уделить 1-2 часа доке MobX, react-mobx и поиграться с ними и все, считай что ты ас и не надо никаких хуков и прочей нечисти, чистые функции так и останутся чистыми.

                                                      +2

                                                      Observable от mobx не имеет никакого отношения к указанным вами observable

                                                        –3
                                                          +3

                                                          Да, совсем. То, что они являются альтернативами друг другу, еще не означает что они чем-то похожи в плане синтаксиса, сложности или кривой обучения.

                                                        +4
                                                        Вся асинхронная логика может реализоваться на чистом Redux через разные уровни Middleware.

                                                        Я вам открою секрет — на чистом Redux через middleware можно вообще реализовать интерпретатор любого ЯП.

                                                        +3
                                                        MobX также увеличивает кривую обучения через Observables

                                                        Вы MobX с RxJS не перепутали?

                                                          +1

                                                          RxJX по мне используют самые отмороженные извращенцы с реактом

                                                            0

                                                            Нет, самые отмороженные используют Angular с NgRx.

                                                              0

                                                              Можно узнать почему?

                                                                0

                                                                Просто взгляни на этот код и потом разматывай клубок чтобы понять че к чему, естественно если этот код написал не ты сам или прошло с момента его написания скажем больше 2х недель. Async/await с 2017 года официально поддерживается, какой нафиг RxJS для реакта, там и так уже давно идеальная эко система в связке с mobx и aync/await

                                                                  0
                                                                  Async/await с 2017 года официально поддерживается, какой нафиг RxJS

                                                                  Какая связь между async/await и rxjs? Это совершенно разные инструменты для решения совершенно разных задач.

                                                                    0

                                                                    Какую задачу решает rxjs что не может решить es2019, реаки и mobx?

                                                                      –2

                                                                      Так я и думал) ответа не будет

                                                                        +1
                                                                        Какую задачу решает rxjs что не может решить es2019, реаки и mobx?

                                                                        Какую задачу решает es2019, реакт и mobx, которую не может решить брейнфак или любой другой тьюринг-полный ЯП?

                                                                    0
                                                                    NgRx — это гремучая смесь идей Redux/Flux, реализованных на основе RxJS. Все это щедро приправлено обязательной хардкорной типизацией TypeScript и кучей индексных файлов с «import * from». Все это с большим скрипом ложится на архитектуру Angular и, само собой, только с Angular и работает.

                                                                    Оригинальный Redux по сравнению с NgRX — образец минимализма и изящества, даже если заморочиться с TypeScript.
                                                                      +1
                                                                      Оригинальный Redux по сравнению с NgRX — образец минимализма и изящества, даже если заморочиться с TypeScript.

                                                                      На самом деле — нет, NgRX значительно проще, концептуально стройнее и изящнее голого Redux'a. Во многом за счет использования rxjs и тайпскрипта как раз.

                                                              0
                                                              -
                                                                0
                                                                Что, если впринципе не использовать state management?
                                                                  –2

                                                                  Нееет, ну что вы. А проблемы? Об чем писать статьи в духе "грабли redux state роутера или как мы ускорили приложение в 1.5 раза переписав все на классы с поддержкой нового бандлинга вебпак". Кому это нужно то? У нас же все тут пишут дико крутые проекты с миллиардами пользователей где без реакта никак ну вообще никак не обойтись. Я не понимаю как вообще мы без него жили до этого?

                                                                    +2
                                                                    Ну нет. Попробуйте написать SPA с 20 типичными юзкейсами на jQuery, потом обсудим, как там клёво на коллбэках.
                                                                      +1

                                                                      Я так понимаю, идея-то заключалась в том, чтобы не писать SPA :-)

                                                                        0

                                                                        Все развалится и будет ад?

                                                                          –1
                                                                          Я думал, ответ и так понятен. Но если быть точным, да: любая толстая бизнес-логика на клиенте, выполненная в императивном стиле, это ад
                                                                            +2

                                                                            Причем тут императивный подход вообще??

                                                                              0
                                                                              По поводу императивного подхода мы действительно мыслим слишком императивно. Поэтому везде где можно сразу начинаем думать а как здесь реализовать экшины. Но есть и другой подход. Например связка react+react router v 4+apollo+graphql. Имеем декларативное описание данных, роутов и все это очень упрощает архитектуру фронтенда
                                                                                +1

                                                                                Когда абстракции выходят из под контроля и все становится не очевидным, тоже такое себе решение, когда все написано черным по белому и сверху вниз, то и проблем в отладке и поддержке не будет, просто открыл код и все интуитивно понятно без магии скрытой от твоих глаз

                                                                                  0
                                                                                  Почему же неочевилным. Как раз более очевидным. Т.к. запрос тут же рядом с описанием компонента например:

                                                                                  import React from 'react';
                                                                                  import { Link } from 'react-router-dom'
                                                                                  import { Query } from 'react-apollo';
                                                                                  import gql from 'graphql-tag';
                                                                                  
                                                                                  const Post = (props) => (
                                                                                    <Query
                                                                                      query={gql`
                                                                                        query {
                                                                                          Post(id: "${props.match.params.postId}") {
                                                                                            id
                                                                                            title
                                                                                            text
                                                                                          }
                                                                                        }
                                                                                     `}
                                                                                      fetchPolicy='network-only'
                                                                                    >
                                                                                      {({ loading, error, data }) => {
                                                                                        if (loading) return <p>Loading...</p>;
                                                                                        if (error) return <p>Error :(</p>;
                                                                                        return (
                                                                                          <ul key='topPosts'>
                                                                                            <li>{data.Post.id}</li>
                                                                                            <li>{data.Post.title}</li>
                                                                                            <li>{data.Post.text}</li>
                                                                                          </ul>
                                                                                        );
                                                                                      }}
                                                                                    </Query>
                                                                                  );
                                                                                  
                                                                                  export default Post;
                                                                                  
                                                                                    0

                                                                                    В данном примере очевидно, но глаза режет) как по мне так запросы надо выносить в отдельную функцию и тем более не использовать это в функциональном-компоненте, он должны быть чистым и простым. Для всего остального есть класс с человеческим жизненным циклом

                                                                                      +1
                                                                                      Т.к. запрос тут же рядом с описанием компонента например:

                                                                                      Запросы в верстке tt.

                                                                                        +1

                                                                                        Когда я впервые познакомился с текстом было недоумение js + html все вместе это же m+v+c сразу. Но почему тогда это работает и даже лучше чем bb (Backbone) где все по фэншую.
                                                                                        В данном примере есть декларативное описание данных но нет самой логики. Поэтому это не модель. Есть декларативное описание ноута но нет действия поэтому это не контроллер. В общем то наверное это и не Вид, т.к. это все не модель mvc, а такое себе декларативное описание компонента

                                                                                          0
                                                                                          Но почему тогда это работает и даже лучше чем bb (Backbone) где все по фэншую.

                                                                                          Потому что не лучше. Это работает, пока у вас маленькие простые write-only проекты вроде фейсбука, у которых цикл разработки год-два, сапортить ничего не надо, а если вдруг что — можно просто выкинуть и переписать с нуля, без особых потерь.
                                                                                          Такие проекты можно писать на чем угодно, и оно будет работать.
                                                                                          Точно так же раньше работал write-only код на php, пока сайты не стали сложными, и с поддержкой говнокода не появились проблемы.

                                                                                  0
                                                                                  -
                                                                        0
                                                                        Использую reduxsauce — количество кода сократилось заметно, декларативное описание action generators, все дела. Тоже вполне себе вариант.
                                                                          0
                                                                          Еще недавно React.PureComponent банально не поддерживался. С версии mobx-react 6.0.0 их рекомендуется использовать и в mobx. А вообще использую в связке с mobx-state-tree.
                                                                            0

                                                                            К слову после того как я увидел mobx-state-tree больше ничего другого использовать не хочется. Redux, как мне кажется, используется по инерции, а также из-за большого количества готовых разработчиков под него.

                                                                              0
                                                                              У меня с mobx-state-tree есть проблема — автокомплит в WebStorm. Для себя я решил это написав на коленке тулзу для генерации JSDoc. А как вы с этим справляетесь?
                                                                                +2

                                                                                Ниже вам уже ответили, переходите на тайп, не представляю как вообще раньше у меня хоть что-то получалось без дженериков и интерфейсов. Сложно только на стадии создания архитектуры, сама разработка даже для других программистов а команде уже не будет представлять сложности. Опять же совершенно божественный автокомплит и рефакторинг в пару действий сильно отрезвляет и даёт понимание, что читстый ES в 2019 допустим только для прототипов, но не как не для серьезных приложений.

                                                                                0
                                                                                Используем MobX в связке с TypeScript, пока 3 месяца — полёт нормальный, удобно. Насколько я понимаю mobx-state-tree тоже проблему типизации решает. Сравнивали с TypeScript или Flow? Есть ли у mobx-state-tree какие-то ещё плюсы?
                                                                                  0
                                                                                  Скорее не типизации, а предсказуемости что в дереве, какая модель, какие методы, какие типы итп.
                                                                                    0

                                                                                    Когда пару лет назад я выбирал, что использовать для типизации, TypeScript попросту оказался мощнее. Опять же без нормальной поддержки в IDE ништяки типизации не так понятны, а поддержка Flow на тот момент была ужасно тормознутая. Как мне кажется, Flow — это полумера. Боитесь чрезмерной строгости — noImplicitAny и прочие параметры компиляции помогают на первых порах. И, опять же, разработчиков на TS, как мне кажется, больше, чем тех кто умеет правильно писать на Flow. От части это связано с тем, что на NG 2 стали использовать TS.
                                                                                    По поводу преимуществ, которые дает mobx-state-tree: ненавижу скринкасты, но в свое время я посмотрел один тьюториал, и понял, какой же фигней я раньше страдал.

                                                                                      0

                                                                                      У mobx-state-tree есть одна киллер-фича — работа с реляционными данными. На уровне снапшотов данных это классический нормализованный стейт, как в Redux. Что позволяет даже использовать Redux Dev Tools. А на уровне бизнес-логики это полноценный объектный граф, как в MobX.

                                                                                    0
                                                                                    Посмотрел на mobx-state-tree. Сразу не понял в чем профит. Выглядит существенно сложнее чем простой mobx. Если можно расскажите что это Вам даёт?
                                                                                      +2
                                                                                      Сериализация для SSR, строгая структура данных, подписка на изменения в дереве в виде JSON-патчей, кэширование view функций, getter'ов. В общем если углубляться там дофига чего нужного есть.
                                                                                        +1

                                                                                        Ну, к слову, JSON-патчи с помощью immer можно получить и в Redux, и в любом другом immutable state manager .


                                                                                        Хотя MobX мне тоже нравится больше. Да и immer написал автор MobX =)

                                                                                      0

                                                                                      Есть один не приятный момент, из-за которого может падать приложение, хотя могло бы и не упасть и продолжить нормально работать, например ты указал что ждёшь от АПИ объект в котором есть свойство price, и ты ожидаешь number, а от АПИ пришла string и все, кирдык. Хотя по сути без разницы для вывода цены будет ли это string или number. Даже если вам надо сложить 2 + "3.5" у вас все равно получится 5.5 как ожидается, так что и для расчетов это тоже не особо актуально в JS, другое дело когда вам придет не "3.5", а скажем "london", тогда все печально, но от такого вас и mobx-state-tree не спасет, он просто упадет. По мне для типизации в помощь при разработке ловчее использовать flow или typescript(если прям реальная потребность в нем есть на проекте). Но для меня для типизации данных от АПИ нету нужды, элементарно просто открыть network и все там видно, в каком формате что и как приходит, тем более как обычно в АПИ в ходе разработки может все меняется и ни раз, и вместо того что исправлять в одном месте, ты всегда исправляешь минимум в двух

                                                                                        0
                                                                                        По моему опыту строгость в апи клиенте Рина сервере идёт только на пользу. У меня был один случай с мобильным приложением. Я бжкжнд писал на codeigniter+mysql. Тк этот стек достался от сайта с которым мобильное приложение было интегрировано. Та в общем то есть что то типа active record в codeigniter и я довольно разработал уже 90%кода когда вдруг обнаружил что драйвер mysql в php числа отдает как строки и я это все так строками и отправляю на мобильное приложение. Короче переделывать было уже поздно так там это и осталось. А если бы было строго то все начало бы валиться сразу и ошибка была бы обнаружена.
                                                                                          0
                                                                                          Я использую superstruct для валидации любых входных данных от апи, как своих так и с 3-й стороны, и вам советую.
                                                                                            +4
                                                                                            Даже если вам надо сложить 2 + «3.5» у вас все равно получится 5.5 как ожидается

                                                                                            Мы сейчас точно точно говорим о JavaScript? При сложении числа со строкой произойдет конкатенация:


                                                                                            2 + "3.5" === "23.5"
                                                                                              +1

                                                                                              Есть один неприятный момент который был описан в множестве хороших книг по программированию. Момент этот называется так: никогда не доверяй данным приходящим извне, проверяй и валидируй… ну или на крайняк изобрети мегатонны супермодных решений чтобы этого не делать.

                                                                                            +2
                                                                                            Согласен с автором по поводу Redux и его библиотек.
                                                                                              0
                                                                                              Кто-нибудь использовал Mobx в крупном SPA-приложении?
                                                                                              Какие у Mobx есть минусы в рамках производительности и сложности развития/поддержки приложения?
                                                                                                +3

                                                                                                Я и более чем на 4х проектах, никаких минусов, сплошные плюсы, реально без сарказма

                                                                                                  +3
                                                                                                  Использовал на 3х проектах. Собственно, на последнем производительность была главным мотиватором переезда с Redux на MobX. Причина почему MobX при всей магии оказывается ещё и быстрее в том, что посто вычислить a + b и оповестить об этом всех подписчиков оказывается быстрее, чем создать объект-экшн, прогнать его про всем редюсерам, сравнить строки, иммутабельно создать новый стейт и если нужно — повторить эту операцию для составных экшнов. Можно каждый из этих шагов оптимизировать, но это будет уже собственное решение. В классическом Redux каждый экшн обрабатывается каждым редюсером (получаем квадратичный рост сложности вычислений), используется сравнительно дорогая операция сравнения строк, вместо дешёвого обращения к методу/свойству объекта, копирование всех свойств в иммутабельную копию так же дороже, чем работа просто с объектом по ссылке, нативные типы вроде Map, Set, Typed Arrays, даже Promise не поддерживаются, в результате их функционал приходится разворачивать в Plan Object, что тоже ест производительность. Вообще, за реализацию и промотирование такой технологии как Redux я бы выгонял из профессии, без права кодить 50 лет. В MobX ничего особенного, он просто написан с применением здравого смысла и заботой о пользователе. Просто работает как нужно, что про него даже статьи не особо пишут (в основном только сравнения), потому что он не является болью.
                                                                                                    +3

                                                                                                    Redux — это хорошая идея с ужасной реализацией. Хорошая идея — это TEA, которая с успехом используется всеми любителями Хаскеля. И даёт все любимые хаскелистами плюхи — чистоту, простоту композиции и рефакторинг в функциональных системах с развитой системой типов.
                                                                                                    Ужасная реализация — это Redux. Который предлагает писать на языке не функциональном, без развитой системы типов, с костыльной дорогой иммутабельностью и кривой функциональной композицией.


                                                                                                    Хочешь бойлерплейта и математического доказательства точности своей программы — пиши на Elm.


                                                                                                    Во всех остальных случаях — бери MobX и не пытайся засунуть квадрат в круглую дырку.

                                                                                                      0
                                                                                                      Хорошая идея — это TEA, которая с успехом используется всеми любителями Хаскеля. И даёт все любимые хаскелистами плюхи — чистоту, простоту композиции и рефакторинг в функциональных системах с развитой системой типов

                                                                                                      Чтобы оно давало плюхи, надо dispatch заменить на иммутабельный. А на данный момент это обычная императивщина, без каких-либо плюх. Экшены не композятся, сайд-эффекты вокруг летают и все вот это вот.

                                                                                                  0
                                                                                                  Чем больше смотрю на код React и Angular, тем больше жду Blazor в продакшене.
                                                                                                    0
                                                                                                    Вам просто не надо использовать никакую оптимизацию в этом случае
                                                                                                    можно забыть о Pure Components, shouldComponentUpdate и что вы там ещё используете в этих случаях
                                                                                                    вы забудете о проблемах с оптимизацией навсегда.

                                                                                                    Может я чего недопонимаю?! Дано: большое сложное приложение, на верхнем уровне меняется @observable значение и компонент верхнего уровня render-ится чтобы отразить эти изменения. Всё древо снизу не мемоизировано (нет PureComputed, Memo, shouldComponentUpdate и пр.). React в рамках 1-ой фазы render-а вынужденно пройдёт по всему древу вглубь до самого последнего листа. Будут вызваны все render методы вашего приложения, будет сформировано с нуля всё vDom-древо вашего приложения, и потом оно же реконслировано (без особого на то смысла).


                                                                                                    Я где-то что-то напутал? Или ^ просто не считается проблемой в мире MobX?

                                                                                                      0

                                                                                                      Любой observer сам по себе мемоизирован. Другое дело, что это достигается либо через memo, либо через PureComponent, либо через shouldComponentUpdate — так что именно с этой стороны ничего нового mobx не предлагает; проставить всем компонентам декоратор observer ничуть не проще чем проставить им всем базовый класс PureComponent.

                                                                                                        0

                                                                                                        Ага, ясно, спасибо. Получается мемоизация на месте, никакой магии тут нет. Впрочем даже в этом случае мемоизация для dump-компонент без mobx не помешает, и react.Memo будет в тему (автору на заметку).

                                                                                                        0
                                                                                                        codesandbox.io/s/summer-shadow-z703e
                                                                                                        Вот смотрите, наглядный пример, перерендер только того, что надо, а не всего дерева если на верхнем уровне изменился стейт.
                                                                                                        +7

                                                                                                        Касательно сравнения redux + anything экосистемы с чем-либо ещё, то мне кажется сравнивать тут нужно сопоставимые решения. В случае mobX нужно было показать пример не с counter-ом, а хотя бы какой-нибудь todo-list. А лучше чего-нибудь крупнее, где будет достаточно витееватое древо данных. И показать не сам mobX а mobx-state-tree или схожие решения. А то вы сравнили тёплое с красным.


                                                                                                        Redux это one-way driven data flow со всеми вытекающими минусами и плюсами. Когда вы берёте себе на вооружение решение такого рода вы обрекаете себя на лишний boilerplate но взамен получаете цельное приложение мимикрирующее под [чистая функция от данных] + [изолированные от view слоя данные] + [изолированная от всего этого business logic]. Это нужно только в крупных приложениях, разработка которых затягивается на многие годы. Совершенно незачем это тащить в приложения малого и среднего размера (в петлю полезете).


                                                                                                        Поэтому все эти сравнения: я в 3 строки написал, то что в redux требуют 10-ка файлов и 200 строк в некоторые степени бессмысленны. Гораздо интереснее и полезнее был бы обзор elm vs react + mobx-state-tree vs vue + vuex vs react + redux + reselect + saga vs angular + rxjs. Все эти связки завязаны на приложения одного масштаба. Хотя сложно отрицать, что их можно написать и проще (но это тема для отдельного холивара).

                                                                                                          0

                                                                                                          Ну, mobx — это тоже one-way driven data flow, если геттеры и сеттеры рассматривать отдельно друг от друга. Только вот почему-то бойлерплейта атм меньше.

                                                                                                            +6

                                                                                                            Я, впервую очередь, имею ввиду "one-driven" в рамках целого приложения. Когда есть отдельная "река данных", как отдельный и цельный, а не разрозненный, слой. И в то же время оторванный от view части. Когда react составляющая это по сути 1 большая pureFunction от данных. Звучит несколько утопично, на деле всё не так радужно, конечно. Но идея именно такова.


                                                                                                            И да такое можно построить и с помощью mobx. Вероятно mobx-state-tree этим как раз и занимается (в эту сторону совсем не копал). И да наверное бойлерплейта там меньше. Вот такие сравнения были бы показательны.


                                                                                                            А текущая статья это как 99% статей про Svelte где вам показывают 2+2 и спрашивают, а чего это вы все ещё не пишете на Svelte? :)

                                                                                                              0
                                                                                                              А текущая статья это как 99% статей про Svelte где вам показывают 2+2 и спрашивают, а чего это вы все ещё не пишете на Svelte? :)

                                                                                                              Вы предлагаете мне сделать аналог фейсбука, чтобы вы смогли оценить преимущества MobX?
                                                                                                                +2

                                                                                                                Для начала вам нужно решить, относительно чего вы хотите показать преимущества MobX. Сравнивать голый MobX и redux довольно бессмысленно. Почему — я выше подробно расписал. Голый MobX вы можете сравнить, скажем, с голым Svelte, с react hooks, с knockout и пр.

                                                                                                                  0
                                                                                                                  Почему — я выше подробно расписал. Голый MobX вы можете сравнить, скажем, с голым Svelte, с react hooks, с knockout и пр.

                                                                                                                  Я сравниваю преимущества MobX по сравнению с flux — архитектурой (на примере Redux) в приложениях на React. Оба они по сути конкуренты — и то и другое представляется как возможность организовать хранение данных на фронте. Статья так и называется — почему вы должны использовать MobX вместо Redux. Почему я должен сравнивать MobX с Svetle, Knockout и react hooks я, честно говоря не очень понимаю.
                                                                                                                    +2
                                                                                                                    Оба они по сути конкуренты — и то и другое представляется как возможность организовать хранение данных на фронте

                                                                                                                    Они не конкуренты. Вот конкурент. Не сравнивайте бульдозер и девятку. Так можно и с jQuery сравнить.


                                                                                                                    Почему я должен

                                                                                                                    Вы никому ничего не должны, что вы.

                                                                                                                      +1

                                                                                                                      Похоже что вы не пробовали MobX в бою, поэтому не имеете о нем полного представления

                                                                                                                      +2
                                                                                                                      Я даже не поленюсь перевезти.

                                                                                                                      Люди часто часто используют MobX как альтернативу Redux. Пожалуйста учитывайте, что MobX — это библиотека для решения вполне определенной технической проблемы. Это не архитектура, сам по себе MobX — это даже не контейнер состояния. Вышеуказанные примеры надуманны, и я рекомендую использовать вам, такие подходы как инкапсуляция логики в методах и организация ее в контроллерах и сторах. Или как кто-то сказал на HackerNews

                                                                                                                      «MobX, уже где-то упоминалось, но не могу не присоединиться. Использование MobX означает, что в архитектуре приложения Вам придется самостоятельно побеспокоится, об использовании таких шаблонов управления потоком данных, как контроллеры/диспетчеры/экшены/супервизоры вместо чего-то предлагаемого по-умолчанию для приложений сложнее списка дел.»

                                                                                                                      Это отсюда если что.
                                                                                                                        –1

                                                                                                                        Ясно, вы один из тех кому что-то сказали и он слепо в это верит, а если ещё и статью кто-то написал так это вообще истина в последней инстанции. Учитесь думать и анализировать своей головой пожалуйста, а не чужими, и опираясь на слова по вашему мнению "авторитета". А ещё было бы круто самому все это попробовать не на уровне hello world и todo и потом уже делать выводы и умозаключения, вместо того чтобы ссылаться на одну из миллионы бесполезных статей и чьих то высказываний которые вводят в заблуждение доверчивых людей, выдавая это за истину и что именно так оно и есть как там написано.

                                                                                                                          +2
                                                                                                                          Ясно, вы один из тех кому что-то сказали и он слепо в это верит, а если ещё и статью кто-то написал так это вообще истина в последней инстанции.

                                                                                                                          Я привел, не статью я рекомендацию автора библиотеки, которую он привел в официальной документации.
                                                                                                                          А ещё было бы круто самому все это попробовать не на уровне hello world и todo

                                                                                                                          А вы попробовали? Поделитесь пожалуйста.
                                                                                                                          ссылаться на одну из миллионы бесполезных статей

                                                                                                                          Полезна ли MobX? Полезна ли документация к ней? Может ли у полезного проекта быть бесполезная документация? А полезная документация у бесполезного проекта?
                                                                                                                            0

                                                                                                                            Я с лично с 2017 года реализовал больше 4х проектов с mobx и все шикарно и без проблем, плюс с этого же периода в нашей компании все начали вместо redux использовать mobx и радости их нету придела по сей день, т.е в рамках нашей компании этих проектов уже больше 10 сложного и среднего уровня и вообще без нареканий, в некоторых пробовали и mobx-state-tree, но в итоге кроме оверхеда и подводных камней — реальной пользы не принес, то чего от него ждут лучше добиться другими путями если уж так надо. Поэтому опыта а меня дофига в реакте с 2015 года как с redux + его зоопарк, так и с mobx с начала 2017 года.

                                                                                                                              +2
                                                                                                                              проектов уже больше 10 сложного и среднего уровня

                                                                                                                              Больше 10 сложных проектов. За 2г. Ух-ты. Что за компания? Несколько сотен разработчиков? :)

                                                                                                                                0

                                                                                                                                200+ сотрудников, из них не все конечно разработчики, но большинство

                                                                                                                          +8
                                                                                                                          Кажется Торвальдс писал, что плохие программисты думают об инструментах, а хорошие — о структуре данных. В последнее время в среде тимлидов мелькает мысль, что можно написать инструменты, которые будут ограничивать программиста и заставлять его писать хороший код. Redux тоже из этой парадигмы. Считаю такой подход не эффективным и даже вредным. Программирование это проежде всего про «думать», а не «писать». Никакой инструмент за вас архитектурные вопросы не решит, это ваша работа, как разработчика. Качество кода имеет смысл повышать образованием, а не органичениями. Иначе люди будут всё равно писать говно, только при этом путаясь в лабиринте навязанных правил, пытаясь их обойти, и обходя там, где не стоило, разрушая весь их смысл. В redux уже так происходит с thunk и saga. Почитайте комментарии Дэна про эти библиотеки, он везде пишет, что они слишком мощные и разрушают идею redux. Но проблема не в них, а в том, что redux, пошёл по пути запретов, а не возможностей. Положился на технологию, а не на людей, в результате люди страдают.
                                                                                                                          Из опыта (а я допытывался примерно у 30 человек, когда работал тимлидом в Яндексе, и примерно столько-же после), больше всего топят за redux люди, для которых это первая подобная технология. Они просто не создавали SPA раньше, не пробывали альтернатив, поэтому верят промо-статьям. К слову сказать, Facebook тоже раньше не создавали SPA, Цукерберг писал на PHP и все знают его авторитарность. Не удивительно, что и React получился похожим на PHP, JSX — просто калька с того, как написаны php-сайты 2000х, js вперемешку с html. Они бы хотя бы посмотрели, как SPA делались в отрасли, но гордыня и самомнение, поэтому сейчас React проходит те же ошибки, которые отрасль прошла 20 лет назад. PR у Facebook хороший, поэтому все новички с ними. Redux тоже вдохновлён серверными языками, но уже другими, функциональными. Хороший сервер должен быть stateless, чтобы можно было распараллелить его на несколько машинок. В серверной разработке часто используют иммутабельные данные, так как это позволяет удобно работать с многопоточностью. На клиенте всё наоборот, но ребята этим никогда не интересовались, поэтому создали говно. Их можно понять, все ошибаются. Нельзя понять тех, кто продолжает топить за это говно, не будучи знаком с другими подходами. Иммутабельность на клиенте — зло. Глобальный стейт мало чем отличается от глобальных переменных, которые зло. Тайм машина классная штука, но нафиг не нужна, если вы не создаёте Text Editor или т.п… Это просто ворует ваше время. Разделять данные и методы — это идея из 70-80, от неё давно ушли, это надуманное бесполезное ограничение.
                                                                                                                          Да, MobX решает одну маленькую просую задачу — обновлять UI когда обновились данные. Эта задача есть в любом приложении и вообще должна бы идти из коробки в React (во Vue и даже Angular это из коробки). Но в Facebook писали на PHP, а не JavaScript, поэтому посчитали это не важным. Redux был создан для демонстрации тайм-машины для конференции, он для этого хорошо подходит, но он не подходит для большинства веб проектов и не решит за вас проблемы с данными, это ваша работа. Не используйте нерелевантные решения не не промотируйте, пожалуйста, а то одинаковые разговоры каждый раз с колегами происходят и никто дальше двух-трёх «Зачем?» root-cause анализ не проходит.
                                                                                                                            +2
                                                                                                                            Тайм машина классная штука, но нафиг не нужна, если вы не создаёте Text Editor или т.п

                                                                                                                            Даже для современного Text Editor с коллаборативным редактированием тайм машина оказывается бесполезна.

                                                                                                                              +1

                                                                                                                              Приятно видеть человека у которого своя голова на плечах и он ей думает.

                                                                                                                                0
                                                                                                                                Почитайте комментарии Дэна про эти библиотеки, он везде пишет, что они слишком мощные и разрушают идею redux.


                                                                                                                                Я бы еще продолжил. Suspense, к созданию которого как я понимаю причастен Д. Абрамов возможно будет плохо или никак сочетаться с redux. Это пока у меня первое такое впечатление. Возможно кто-то сочинит еще аналог thunk тол ько теперь для работы с Suspense
                                                                                                                                  +2
                                                                                                                                  JSX — просто калька с того, как написаны php-сайты 2000х

                                                                                                                                  Я бы не был так категоричен, по моему мнению это лучший на сегодня шаблонизатор, максимально приближенный к html. В отличие от Vue и Angular, где в кастомных атрибутах в виде строк описывается логика работы — подход, с которым сообщество борется десятки лет, но он почему-то жив и приобретает новые формы.


                                                                                                                                  В последнее время в среде тимлидов мелькает мысль, что можно написать инструменты, которые будут ограничивать программиста и заставлять его писать хороший код

                                                                                                                                  На моей практике стандарты кодирования и стандарты качества (неинструментальные, но все же ограничения) способствуют формированию общности в среде разработчиков, если создаются демократическими методами. ESLint туда же. Не в одном проекте видел достаточно образованных разработчиков, которые в одной кодовой базе использовали кардинально разные подходы — с типизацией/без, функциональный стиль/ООП, thunk/saga, даже различные методы именования переменных. Нельзя сказать, что код каждого был плохой — но при уходе разработчика другим приходилось переписывать то, что он делал, так как не понимали его код.


                                                                                                                                  В остальном согласен, разве что только не MobX обновляет UI, а все же React в данном случае, просто эффективней (хотя крайне мало проектов, в которых важно — обновилось 10 компонентов или 1)

                                                                                                                                    0
                                                                                                                                    Я бы не был так категоричен, по моему мнению это лучший на сегодня шаблонизатор, максимально приближенный к html.

                                                                                                                                    Так "максимально приближено к html и разбавлено вставками хост-языка" — это и есть пхп-поход. В фейсбуке только заменили строки на хмл-подобную нотацию. И, с-но, с этим реакт-подобным подходом как раз сообщество и боролось — в результате чего появились полноценные шаблонизаторы. Именно так, а не наоборот. Ну, на бекенде.
                                                                                                                                    На фронте же развитие сразу началось с современных технологий (с шаблонизаторами) — но в фейсбуке решили портировать свой устаревший пхп-движок (xhp) на js, видимо, для того, чтобы удобнее было переносить протухшее легаси, и… эта песня хороша, начинай сначала — технологический уровень фронта отбросило на десяток+ лет назад.

                                                                                                                                    +4

                                                                                                                                    Удивительный комментарий. В первом абзаце идут здравые вещи, а дальше – какой-то набор антипаттернов.


                                                                                                                                    Цукерберг писал на PHP и все знают его авторитарность. Не удивительно, что и React получился похожим на PHP

                                                                                                                                    React появился когда Facebook уже был многомиллионной компанией. Вы всерьез верите что CEO Facebook лично принимал участие в дизайне React? А БЭМ в Яндексе под личным контролем Воложа и Сегаловича придумали?


                                                                                                                                    JSX — просто калька с того, как написаны php-сайты 2000х, js вперемешку с html.

                                                                                                                                    Если это единственное что вы увидели в React, то вы не поняли этот фреймворк совсем.


                                                                                                                                    Они бы хотя бы посмотрели, как SPA делались в отрасли, но гордыня и самомнение, поэтому сейчас React проходит те же ошибки, которые отрасль прошла 20 лет назад

                                                                                                                                    Почему вы считаете что не смотрели? В отрасли были Angular и Backbone. React перенял их опыт. Были даже гибридные Backbone+React решения.


                                                                                                                                    Какие ошибки вы можете назвать?


                                                                                                                                    Глобальный стейт мало чем отличается от глобальных переменных, которые зло.

                                                                                                                                    Глобальный стейт больше похож на шину данных, чем на просто переменные. Общая шина данных тоже зло?


                                                                                                                                    никто дальше двух-трёх «Зачем?» root-cause анализ не проходит.

                                                                                                                                    Вот это хороший совет, но вы сами ему не следуете. Более глубокий анализ помог бы вам избежать этих заблуждений, которые вы демонстрируете выше.

                                                                                                                                      0
                                                                                                                                      React появился когда Facebook уже был многомиллионной компанией. Вы всерьез верите что CEO Facebook лично принимал участие в дизайне React?

                                                                                                                                      React — это порт XHP, а XHP появился задолго до реакта. А архитектура кода, под который писался XHP — конечно же, задолго до самого XHP. Так что преемственность тут прослеживается весьма четко.


                                                                                                                                      Если это единственное что вы увидели в React, то вы не поняли этот фреймворк совсем.

                                                                                                                                      "быть как php-серверсайд" — основа идеалогии реакта, которая видна практически во всех архитектурных решениях — начиная со способа рендеринга (это вообще смешная история — чтобы "быть как серверсайд" людям пришлось даже целую хитрую оптимизацию в виде vdom выдумать) и заканчивая видом шаблонизатора.
                                                                                                                                      Непонятно, как это можно отрицать. С-но, это даже и сами разработчики не отрицают.

                                                                                                                                        +1
                                                                                                                                        А БЭМ в Яндексе под личным контролем Воложа и Сегаловича придумали?

                                                                                                                                        Естественно высшему руководству показывали презентации, а они что-то утверждали, а что-то нет. Сейчас Парахин, например, очень активно в технологической стандартизации участвует и лично вникает в детали. Плюс руководство в любой компании нанимает близкий к себе по взглядам людей. Так в Яндексе очень сильно влияние фронденд-культуры и культуры машинного обучения. В Facebook не работал, но по многим признакам видно, что культура там другая, и это не в их пользу.

                                                                                                                                        Если это единственное что вы увидели в React, то вы не поняли этот фреймворк совсем.

                                                                                                                                        Просветите? setState который по хорошему пора заменить геттерами-сеттерами? Или хуки, которые являются органиченной версией наблюдателя? Или контекст, который разрушает инкапсуляцию? Что вас привлекает в React? Несмотрю на стёб я считаю JSX хорошим решением. Мой тезис в том, что так как ребята не специализировались на фронтенде — они допустили множество других ошибок, которые портят это решение.

                                                                                                                                        Какие ошибки вы можете назвать?

                                                                                                                                        Прежде всего ошибку приоритезации: они решали проблему, которой не было, и не решили актуальные. В частности обновление view при обновлении model (из за чего мы и имеем пляски с Redux, MobX, т.п.). Для сравнения, Vue не только решили эту проблему из коробки, а так же добавили биндинги вроде onkeypress.enter или onclick.preventdefault, что мелочи, но сразу показывает, что они в теме, так как это очень частые операции. Сравните с навешиванием событий в React, когда до стрелочных функций приходилось писать bind в конструкторе на каждый обработчик. Это очень частая операция, очевидно нужно сделать её краткой и удобной, но ребята этого не понимают. Я не думаю, что они глупые, я думаю у них просто не тот бекграунд. Они никогда не создавали SPA на нативном JS и не знакомы с культурой, стандартами и лучшими практиками, поэтому навязывают сообществу свои, «революционные», на самом деле непродуманные.

                                                                                                                                        Глобальный стейт больше похож на шину данных, чем на просто переменные. Общая шина данных тоже зло?

                                                                                                                                        Общая шина нарушает фрактальную природу программы. Можно использовать её в какой-то части программы, можно во всей программе, если программа маленькая, но общая шина не масштабируется. Представьте, если бы весь интернет, все уровни OSI были написаны с использованием одной шины, без разделения на слои? В своё время я запрещал своим сотредникам, начитавшимся хайпа, использовать глобальную шину во фронтенде, и ни разу не пожалел об этом, потому что модульность и возможность инкапсуляции гораздо более ценны, а глобальная шина ничем не лучше локальных наблюдателей. Даже если нужно сделать сквозной функционал, вроде логирования всех событий, я бы продпочёл это делать локальными шинами, наследуемыми от общего родителя (простой вариант), или через Стратегию с передачей логгера композицией, или через dependency injection, что не особо популярно в js-среде, но очень мощно, гибко и не обладает таким количеством недостатков, как глобальная шина. Случай из моей практики когда шина действительно хорошо сработала — геймдев, бекенд, около 50 сущностей, каждая из которых влияет на множество других (действия, перки, скилы, предметы, другие игроки и их аттрибуты). Когда у вас есть кластер из сильно связанных сущностей (и связанных не из-за плохой архитекруры, а по бизнес-требованиям), решением будет или шина или медиатор, шина часто оказывается проще. Но таких приложений мало. И даже в этом случае шину имеет смысл делать не истинно глобальной, а общей на сильносвязанный кластер классов.

                                                                                                                                        Вот это хороший совет, но вы сами ему не следуете

                                                                                                                                        Не говорите гоп пока не докажете ошибочность моих суждений (за что буду благодарен). Пока ничего не доказали
                                                                                                                                  +3
                                                                                                                                  Плюсую, чтобы написать counter не нужна библиотека для управления состоянием. Актуальнее описать какие проблемы возникают при написании больших React приложении, и как каждая из библиотек пытается их решать.
                                                                                                                                    +2

                                                                                                                                    Redux и MobX решают одну и ту же проблему/задачу, если не разводить демогогию и цепляться к мелочам. Из моего опыта все кто опробовал MobX в бою больше никогда к Redux не возвращался, конечно же будут индивидумы которые попробовав в бою MobX останутся с Redux'ом, но я таких не знаю. Знаю только тех кто топит за Redux начитавшись непонятных статей и не попробовав при этом MobX на своей шкуре.

                                                                                                                                      0
                                                                                                                                      Даже потратив 5 минут, уже могу сказать, что эти библиотеки решают разные проблемы.

                                                                                                                                      ru.wikipedia.org/wiki/Flux-%D0%B0%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0

                                                                                                                                      github.com/mobxjs/mobx

                                                                                                                                      Unlike many flux frameworks, MobX is unopinionated about how user events should be handled.

                                                                                                                                      This can be done in a Flux like manner.
                                                                                                                                      Or by processing events using RxJS.
                                                                                                                                      Or by simply handling events in the most straightforward way possible, as demonstrated in the above onClick handler.
                                                                                                                                        –1

                                                                                                                                        Как насчёт того чтобы просто подумать именно своей головой и пощупать и то и другое и вы удивитесь, что действительно и то и другое нужно для одного и того же, философия и подход, вот в чем различие. Изменяешь состояние и твои компоненты которые следят за ним перерендериваются, вот и все предназначение у обоих. Потому хранить состояние без перерендера вы можете как угодно и где угодно, а тут нужна реактивность, т.е. реакция компонентов на изменение состояния в приложении.

                                                                                                                                          +1
                                                                                                                                          Так если Вы уверяете всех, что имеете богатый опыт, поделитесь им. С какими проблемами Вы сталкивались? У вас не перерисовывался компонент? или что-то посложнее?

                                                                                                                                          Пока вижу только доводы в духе: «Мне и моим одноклассникам всё понравилось».
                                                                                                                                            +3

                                                                                                                                            Так не было ни проблем, ни боли с mobx и нету по сей день

                                                                                                                                        0
                                                                                                                                        Знаю только тех кто топит за Redux начитавшись непонятных статей и не попробовав при этом MobX на своей шкуре.

                                                                                                                                        А я знаю тех, кто топит за React и Angular, не попробовав $mol на своей шкуре.

                                                                                                                              0

                                                                                                                              Бойлерплейта нету

                                                                                                                            +1

                                                                                                                            Не соглашусь со статьей, так как моб не учит писать чистый код. У меня есть тому пример. Я пришёл на проект где был моб, схема данных простая — 5 уровней разных энтити, вложенных друг в друга (1 ко многим).


                                                                                                                            Приложение маленькое (не сайт резервации и не фейсбук), но открывалось оно пустым 3 секунды, пока апи не существовало.


                                                                                                                            Для тестов одного контейнера 2го уровня например чуваки инжектили весь стор.


                                                                                                                            Обсерваблы и инжекты были везде и бестолково, часто dead


                                                                                                                            Сторы писались фактори функцией от которой наследовался каждый класс различной энтити.


                                                                                                                            Я выпилил это все счастье и юзаю сегодня redux, thunk, reselect и все этот связке с ducks pattern. Работает замечательно, код понятнее в разы, а также намного лучше масштабируется и тестируется.


                                                                                                                            Не скажу что у меня все идеально, тех же фактори у меня пока нет. Но я рад что избавился от моба.

                                                                                                                              +2
                                                                                                                              Некоторые аргументы очень странные:

                                                                                                                              Да, всё верно, вместо каких-то функций, которые изменяют объекты, вы можете использовать классический ООП подход, с классами, их свойствами и методами.

                                                                                                                              Ок, и зачем мне классический ООП в приложении где пропагандируется функциональный подход, все данные иммутабельны, а классов нет вообще?

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

                                                                                                                              Это легко абстрагируется. Например, redux-form хранит данные всех форм в редаксе и не заставляет писать бойлерплейта вообще. Ничего не мешает абстрагировать подобным образом, допустим, все запросы к API или любые другие повторяющиеся элементы стора.

                                                                                                                              Если посмотреть примеры выше, то можно увидеть, что в случае с MobX я не использовал pure component и это не ошибка.

                                                                                                                              Зато использовал его в случае с редаксом и это ошибка. Редакс считает все компоненты чистыми по умолчанию и не перерендеривает их, если mapStateToProps вернул эквивалентный результат.

                                                                                                                              Про setState аргумент вообще надуманный и большая часть примеров с ним это просто плохой код. Например, передача в setState объектов, хранение там таймеров, использование хуков без зависимостей и тому подобное.
                                                                                                                                0
                                                                                                                                Ваше мнение о lostpebble.github.io/pullstate интересует
                                                                                                                                  +1

                                                                                                                                  Не советую, функции должны быть чистыми и простыми без своего состояния, для всего остального есть классы с человеческим жизненным циклом, а в качестве стейт менеджмента сбоку используйте MobX или Redux. Сэкономит время и нервы в будущем вам и тем, кому придется иметь дело с вашим кодом и вашей архитектурой. MobX ещё сэкономит вам прилично времени и полностью развяжет руки, стоит только попробовать и все, обратно уже не захочется)

                                                                                                                                    0

                                                                                                                                    Основная проблема таких проектов — отсутствие коммъюнити, и как следствие, фрагментация.
                                                                                                                                    Есть куча библиотек, построенных вокруг использования Proxy для отслеживания изменений. Например:


                                                                                                                                    • easy-peasy — Redux-like стор с Immer внутри и селекторами снаружи
                                                                                                                                    • react-tracked — а здесь наоборот, Proxy используются для отслеживания зависимостей при рендеринге, как в MobX
                                                                                                                                    • overmind — а здесь реализованы обе фичи, почти как mobx-state-tree. Но нет JSON-patch и объектного графа.
                                                                                                                                    0
                                                                                                                                    хорошо бы сравнить еще с vuex
                                                                                                                                      +1

                                                                                                                                      Vuex надо сравнивать в контексте Vue, а тут React.js. Vue + Vuex дружелюбная штука после реакта, в отличие от ангуляра. Но тут уже дело вкуса, я пробовал боевые задачи делать на vue чтобы реально оценить и сравнить для себя с реактом, пришел к выводу что react + mobx серебряная пуля для задач и проектов любой сложности, просто нужен большой опыт и умение все это готовить, я не вижу даже что ещё можно улучшить в реакте или в мобе чтобы было ещё приятнее кодить, все это в купе с es2019 для меня просто эталон. По желанию можно прикручивать typescript, но там тоже есть нюансы.

                                                                                                                                        0
                                                                                                                                        Для typescript есть ангуляр. Так по вашему опыту, реакт показал себя лучше vue?
                                                                                                                                          0

                                                                                                                                          Для меня да, реакт более изящный и красивый нежели vue, про angular вообще молчу. Vue и Angluar это именно фреймворки которые диктуют свои правила и загоняют в рамки, а реакт это просто библиотека, но именно в умелых руках превращается в идеальный инструмент для SPA

                                                                                                                                          0
                                                                                                                                          я не вижу даже что ещё можно улучшить в реакте или в мобе чтобы было ещё приятнее кодить
                                                                                                                                          Например, можно еще:
                                                                                                                                          1. Сделать уже из реакта фреймворк, а не конструктор фреймворков. Хорошо, когда есть возможность писать с нуля и самому выбирать технологии. Но в реальности из-за запросов заказчика и скорого дедлайна зачастую приходиться брать готовые решения, каждое из которых реализовано по разному и на разных технологиях, и которые надо переделывать под проект. И тут тебя еще «радуют» проблемы популярных решений.
                                                                                                                                          В vue удобно сделано. Можно при установке выбрать, что ставить (vuex, router)
                                                                                                                                          2. Композицию сделать на props, а не на компонентах, чтобы уже перестать смешивать логику и view, и не писать очередные замены миксин.
                                                                                                                                          3. Условия, циклы в jsx добавить.
                                                                                                                                          4. Двунаправленный биндинг добавить. Можно конечно стейт передавать в кастомные input и самостоятельно реализовать биндинг. Но это не вариант.

                                                                                                                                          Уверен, еще много чего найдется улучшить.
                                                                                                                                            0

                                                                                                                                            Для меня это не улучшения, а наоборот, если вам это надо, то вам надо писать на vue или angular или ещё на чем нибудь.


                                                                                                                                            То какой сейчас react, mobx и ecmascript, более чем достаточно для тех, кто умеет это готовить.


                                                                                                                                            По поводу заказчиков, никто вам не мешает найти нормальную работу, где нету этого булшита тяп ляп и на скорую руку лишь бы работало. Тут вы никогда не станете реальным спецом. Я последнее 3 года от такой работы просто отказываюсь и работаю только на проектах с нуля где не надо чтобы все работало похер как, лишь бы побыстрее закодить. И поэтому пишу всегда в свое удовольствие и закладываю наработанную с годами архитектуру и постоянно ее совершенствую и не знаю никаких бед и проблем. Mobx, react, moment, axios и все, больше ничего не юзаю, кроме редких исключениях типо задачи когда надо например визуальный редактор html прикрутить.

                                                                                                                                              0
                                                                                                                                              Смысл переходить на vue или angular, если там всего этого тоже нет)

                                                                                                                                              Это хорошо, что у вас все так хорошо сложилось. Я в жизни не видел ни одного разраба, ни одной фирмы, где прям все хорошо. Только если на словах. У всех свои проблемы. Ладно, не об этом речь.
                                                                                                                                                0
                                                                                                                                                Наконец-то то я вернулся домой и теперь за компом, теперь можно нормально писать, а не с телефона)
                                                                                                                                                1,3,4 пункты как минимум присутствуют в Vue
                                                                                                                                                А по второму пункту — смешивание логики и view, ну тут уже все зависит только от того, как код напишите, это не реакт ставит вас в какие-то жесткие рамки
                                                                                                                                                  0
                                                                                                                                                  Насчет 1 и 3 пункта, сомневаюсь.
                                                                                                                                                  Полноценный фронтенд фреймворк для меня, это когда можно из доступных из коробки фич сделать приложение с клиент-серверным взаимодействием, валидацией, роутингом, стором без явной необходимости скачивать плагины, делающие эти фичи гораздо лучше фреймворка.
                                                                                                                                                  Что касается циклов и условий в реализации JSX для Vue, я не знаю, есть ли они там. С Vue я мало знаком.
                                                                                                                                                  Ну и к тому же в Vue тоже свои недостатки есть. Не думаю, что один из них (react, vue) настолько лучше другого, что при знании одного, стоит переходить на другой.

                                                                                                                                                  По второму пункту.
                                                                                                                                                  Реакт изначально делался со смешиванием логики и view. Разделить то можно, до тех пор, пока нескольким компонентам не понадобится общая логика. Решения вроде миксин и HOC по вынесению общей логики вне компонентов не очень себя показали. Решения аналогичного директивам попросту нет. Тут все-таки реакт ставит в жесткие рамки. В общем, реакт гибкий, но мог бы быть еще гибче.
                                                                                                                                                  Да, появились хуки. Но неизвестно, куда они заведут. Через пару лет видно будет.
                                                                                                                                                    0
                                                                                                                                                    Думаю я не открою америку, но у большинства разработчиков (я не исключение) уже давно написан и подготовлен каркас (который всегда естественно модернизируется чтобы быть лучше и лучше в последующих проектах) в котором уже заложена архитектура и базовые компоненты которые вам так необходимы, такие как роутинг, валидация форм и т.д. и т.п. это не нужно писать каждый раз с нуля, ты как бы собрал свой собственный фреймворк как конструктор и используешь его, используя только плюсы той или иной библиотеки, а если они все или какая-то из них говно, то просто пишешь свое решение и используешь его.
                                                                                                                                                0
                                                                                                                                                Mobx, react, moment, axios и

                                                                                                                                                … приложение уже весит 125 кб со всеми способами сжатия.


                                                                                                                                                Для сравнения: весь mol.js.org — 85кб даже без минификации.

                                                                                                                                                  0
                                                                                                                                                  На дворе 2019 год, 1 раз загрузил(очень и очень быстро, если ты не а африке живешь) и всё, оно у тебя в кэше.
                                                                                                                                                  Делай генерацию html на бэке и забудь о JS на клиенте, ну или прям по минимому, так у тебя вообще весь будет, это вес твоей странички

                                                                                                                                                  Если это landing page, то есть смысл сделать так, что бы первая загрузка была максимально быстрая, если у тебя это именно приложение, то вообще пофиг, это последнее на что стоит смотреть, тем более если уже так хочется, то можно сделать SSR и пользователь увидеть все при первой загрузки так же быстро и сразу, а интерактивность начнется уже когда (очень очень быстро) загрузится и положится в кэш твой бандл
                                                                                                                                                    0

                                                                                                                                                    А не думали выкинуть moment в пользу какого-нибудь модульного date-fns? Это существенно уменьшит вес бандла. Единственное, чем можно объяснить сейчас использование moment — это legacy. Или библиотеки UI компонентов под реакт, где он прописан в зависимостях.

                                                                                                                                                      0
                                                                                                                                                      Да я на самом деле обычно вообще с датами работаю самостоятельно написав только функцию для приведения в нужный формат и конвертер в формат который требуется для бэка, в 95% только это и требуется. А moment я указал так чисто, для особо ленивых, как привычную либу)
                                                                                                                                                        +1

                                                                                                                                                        Заменить moment на date-fns (или вообще на Intl), axios на fetch, а react на preact :)


                                                                                                                                                        А вот мы не можем отказаться от moment из-за moment-timezone (да, приходится обрабатывать на клиенте) и его более широких по сравнению со стандартным Intl возможностей по форматированию дат.

                                                                                                                                                        0

                                                                                                                                                        И зачем мне ваши костыли? У меня нет проблем с размером приложения.

                                                                                                                                                  –2
                                                                                                                                                  Присоединяюсь к «выводу что react + mobx серебряная пуля для задач и проектов любой сложности» — задачи, стоящие перед frontend-разработкой решаются насколько элегантно, что не приходится раскручивать цепочки вида компонент-родительский компонент-контейнер-селектор-экшен-тип экшена-поиск затрагиваемых сторов-обработчик АПИ запросов-нормализатор, которые присутствуют в более-менее сложных проектах на Redux. Практически ничто не мешает свободному полету мысли и созданию качественного приложения. Разве что Typescript я бы все же не прикручивал — мороки намного больше, чем профита, по моему опыту.
                                                                                                                                                    –3
                                                                                                                                                    Красавчик, я рад что хоть нас и меньшинство, но все же мы есть (те кто мыслят критически и насрать на любой «авторитет», делай именно так как реально удобно, комфортно и т.п., для этого своя голова на плечах и есть)
                                                                                                                                                    P.S я тоже против Typescript на фронте, на бэке ещё можно подумать.
                                                                                                                                                  +1
                                                                                                                                                  Как раз зашёл чтобы оставить комментарий про vue :)

                                                                                                                                                  Если в двух словах, то vue, кажется, умеет из коробки всё, что умеет mobx. Ну например, давайте сделаем счётчик с моделью, по всем канонам mobx:

                                                                                                                                                  models/counter.js
                                                                                                                                                  export default {
                                                                                                                                                    counterValue: 0
                                                                                                                                                  }

                                                                                                                                                  components/counter.vue
                                                                                                                                                  <template>
                                                                                                                                                    <h1>Counter value: {{model.counterValue}}</h1>
                                                                                                                                                  </template>
                                                                                                                                                  
                                                                                                                                                  <script>
                                                                                                                                                  export default {
                                                                                                                                                    name: 'Counter',
                                                                                                                                                    props: ['model']
                                                                                                                                                  }
                                                                                                                                                  </script>

                                                                                                                                                  App.vue
                                                                                                                                                  <template>
                                                                                                                                                    <div id="app">
                                                                                                                                                      <Counter v-bind:model="counterModel" />
                                                                                                                                                    </div>
                                                                                                                                                  </template>
                                                                                                                                                  
                                                                                                                                                  <script>
                                                                                                                                                  import counterModel from './models/counter.js';
                                                                                                                                                  import Counter from './components/Counter.vue';
                                                                                                                                                  export default {
                                                                                                                                                    name: 'app',
                                                                                                                                                    components: {Counter},
                                                                                                                                                    data: () => ({counterModel})
                                                                                                                                                  }
                                                                                                                                                  </script>


                                                                                                                                                  Даже следить за изменением свойств можно: просто добавить в компонент
                                                                                                                                                  watch: { 'model.counterValue': function(value){} }
                                                                                                                                                    0
                                                                                                                                                    Ах да, я же не написал обновление счётчика?

                                                                                                                                                    components/counter.vue
                                                                                                                                                    <template>
                                                                                                                                                      <div>
                                                                                                                                                        <h1>Counter value: {{model.counterValue}}</h1>
                                                                                                                                                        <button v-bind:click="incrementValue"> + </button>
                                                                                                                                                      </div>
                                                                                                                                                    </template>
                                                                                                                                                    
                                                                                                                                                    <script>
                                                                                                                                                    export default {
                                                                                                                                                      name: 'Counter',
                                                                                                                                                      props: ['model'],
                                                                                                                                                      methods: {
                                                                                                                                                        incrementValue: function(){
                                                                                                                                                          this.model.counterValue++;
                                                                                                                                                        }
                                                                                                                                                      }
                                                                                                                                                    }
                                                                                                                                                    </script>
                                                                                                                                                      +2

                                                                                                                                                      Логично, Vue это фреймворк, а не библиотека чисто для рендеринга как реакт, который усиливается mobx и становится идеальным))