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
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 477

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

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

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

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

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

            +4
            Вчера проходил собеседование, типичная ситуация, проект полу дохлый:
            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, то берётся он, иначе создаётся новый и ему проставляется этот аттрибут.
                            0

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

                              0

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

                              0

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

                          0

                          Вполне себе удобно получилось:
                          https://github.com/eigenmethod/mol/tree/master/jsx/make#usage-example

                            +1

                            Нет. Необходимость присваивать всем элементам id — это не удобно.

                              –2

                              Эта необходимость есть в любом случае для проекта сложнее "привет, мир". Разница лишь в том, насколько удобно это делать.

                  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 с сериализацией все вроде бы просто а вот десериал щация идёт в отдельном проекте
                              +1

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

                                +1
                                Это вопрос с запутанной историей. Ява скрипт умеет скорее всего только 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

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

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

                              +1

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

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

                                Ну так дергаете и рендерите, в чем там проблема и как с ней связано 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

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

                                        +6
                                        Логику можно разделить на логику отображения и логику обработки данных. Логику отображения храните в компонентах React, логику обработки данных вместе с данными, которые эта логика обрабатывает. Никаких минусов такого подхода за долгие годы не обнаружил, наоборот фичи получаются более локализованные.
                                          0
                                          Согласен, такой подход позволяет убрать всю бизнес логику из компонентов, оставить в них только логику отображения. Тут тоже несколько плюсов:
                                          1. Компоненты становятся меньше и соответственно более понятно, что в них происходит
                                          2. Если в компонентах фигачить бизнес-логику, она будет пересчитываться каждый раз, когда этот компонент будет перерендериваться, а это минус к производительности
                                          3. Компоненты становятся менее зависимыми от данных == больше шанс их переиспользовать.
                                          –2
                                          Можно создать отдельный класс в котором будут данные и отдельный класс в котором будут методы. Лично я предпочитаю хранить и данные и методы для этих данных в одном классе:
                                          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

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

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

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

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

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

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

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

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

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


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


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


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


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

                                                      –3
                                                      Во-первых, при наличии таких операций как 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?
                                                                    –3

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

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

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

                                                                          0

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

                                                                            0
                                                                            Я думал, ответ и так понятен. Но если быть точным, да: любая толстая бизнес-логика на клиенте, выполненная в императивном стиле, это ад
                                                                              +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 =)

                                                                                        –1

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

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

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


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

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

                                                                                              +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
                                                                                                          Вот смотрите, наглядный пример, перерендер только того, что надо, а не всего дерева если на верхнем уровне изменился стейт.
                                                                                                          +8

                                                                                                          Касательно сравнения 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 в бою, поэтому не имеете о нем полного представления

                                                                                                                          0

                                                                                                                          Ну по идее статья написана именно для таких людей? Те, кто пробовал и redux, и mobx, обычно имеют собственное мнение.

                                                                                                                            0

                                                                                                                            Похоже, статья написана для людей, которые используют redux, но не в восторге от его подходв.

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

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

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

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

                                                                                                                          Ясно, вы один из тех кому что-то сказали и он слепо в это верит, а если ещё и статью кто-то написал так это вообще истина в последней инстанции. Учитесь думать и анализировать своей головой пожалуйста, а не чужими, и опираясь на слова по вашему мнению "авторитета". А ещё было бы круто самому все это попробовать не на уровне 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
                                                                                                                                    +3
                                                                                                                                    JSX — просто калька с того, как написаны php-сайты 2000х

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


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

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


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

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

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

                                                                                                                                        0

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


                                                                                                                                        JSX — это обычный шаблонизатор для HTML, который имеет хорошую и максимально приближенную к Javascript модель для программирования шаблонов.


                                                                                                                                        И да, внутри JSX нельзя ходить в базу и делать запросы на сервер, как нельзя их делать, например, в шаблонах Ангуляра (хотя можно делать в компонентах).

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

                                                                                                                                          Нет, ПХП-подход (ну, тот самый канонический говно-ПХП подход; понятное дело что и на пхп многие пишут по-человечески) — это вермешель из кучи маленьких ф-й, каждая из который выплевывает небольшие куски хтмля.

                                                                                                                                            0
                                                                                                                                            И да, внутри JSX нельзя ходить в базу и делать запросы на сервер

                                                                                                                                            Точно нельзя? Что-то вроде '<input value={fetch(), this.props.value}} />` не прокатит?

                                                                                                                                      +5

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


                                                                                                                                      Цукерберг писал на 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 выдумать) и заканчивая видом шаблонизатора.
                                                                                                                                        Непонятно, как это можно отрицать. С-но, это даже и сами разработчики не отрицают.

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

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

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

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

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

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

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

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

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

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

                                                                                                                                            Не, дело не в глупости и не в бекгруанде, а в квадратно-гнездовом способе мышления.
                                                                                                                                            Достаточно issues на гитхабе почитать — там постоянно возникает ситуация когда фичу Х не делают удобной для 99% кейзов т.к. она станет неудобна в 1% оставшихся кейзов. Вместо этого ее делают удобной для 1% кейзов и, с-но, неудобной для остальных 99%. Понятно, что тут нет логики — но это стандартный способ рассуждения разработчиков реакта. Именно оттуда и упомянутые вами костыли с пробрасыванием ф-й в качестве пропсов — это вполне осознанные решения все.

                                                                                                                                              0
                                                                                                                                              Неудобно для кого-то !== Неудобно для всех.
                                                                                                                                              Когда кто-то думает что это не удобно для всех по любому, скорее всего это не так) Все люди разные и для всех удобства разные.
                                                                                                                                                +3
                                                                                                                                                Неудобно для кого-то !== Неудобно для всех.
                                                                                                                                                Все люди разные и для всех удобства разные.

                                                                                                                                                В данном случае речь не для кого, а в каком случае, и под удобством подразумевается полностью объективная (т.е. для всех одинаковая) вещь. Когда вам не надо совершать специальных действий для использования фичи — это удобно. А когда надо — это неудобно.
                                                                                                                                                Вот хорошая архитектура — это такая, в которой удобно для стандартных кейзов и неудобно (опционально) для нестандартных. А в квадратно-гнездовой архитектуре — все наоборот. Реакт — типичный пример квадратно-гнездовой архитектуры.


                                                                                                                                                Ну вот конкретный пример — PureComponent и функции в качестве пропсов. Если вы просто сунете лямбду в пропс, т.е. совершите стандартные распространенные действия, то ваша PureComponent сломается. Т.е. PureComponent по дефолту сломан и не работает в стандартном сценарии использования. По-этому вам надо наворачивать бойлерплейт, чтобы это обойти. Ну или реализовывать свои обертки. С другой стороны — вам не надо ничего делать дополнительно в том исключительном случае, когда вам действительно надо трекать изменение пропса-функции.
                                                                                                                                                ЭЖто архитектура квдаратно-гнездовая.
                                                                                                                                                Если бы архитектура была нормальная, то вам бы ничего не надо было делать в стандартном случае, а вот в случае, если вы хотите оттрекать изменение ф-и — это всегда можно было бы сделать в shouldComponentUpdate
                                                                                                                                                На самом деле с PureComponent ситуация даже еще более печальна и это не единственный косяк архитектуры, но самый показательный.

                                                                                                                                                  +1
                                                                                                                                                  Когда вам не надо совершать специальных действий для использования фичи — это удобно. А когда надо — это неудобно.

                                                                                                                                                  Питонисты, да и вообще фанаты строго типизированных языков с вами не согласятся. :) "Явное лучше неявного" и так далее. Надо чётко объявлять типы в коде, явно кним приводить, а не доверять автоматическому приведению в PHP или JS. А для сторонников слабой типизации и "магии" языков и фреймворков удобно написать пару строк для решения задачи, а не мучаться с соответствием типов.

                                                                                                                                                    0

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

                                                                                                                                                      +1

                                                                                                                                                      Я наблюдаю, что в программах на строго типизированных языках есть нефункциональный код связанный с типобезопасностью. Декларации самих типов, объявления типов переменных, параметров, результатов и т. п., формальные (без изменения данных) приведения типов и т. п. Вы считаете, что этот код никак не связан с тем, что языки строго типизированы? Или считаете, что для появления этого кода не совершаются никем никакие дополнительные действия?

                                                                                                                                                        0

                                                                                                                                                        Как правило, у этого кода есть некоторая цель, отличная от просто использования фичи. А если такой цели нет — от него точно так же стремятся избавиться.

                                                                                                                                                          –1

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

                                                                                                                                                      +1
                                                                                                                                                      Питонисты, да и вообще фанаты строго типизированных языков с вами не согласятся. :) "Явное лучше неявного" и так далее.

                                                                                                                                                      Здесь явное/неявное не при чем. Я говорю о том, что вам либо приходится совершать некие специальные действия, чтобы все заработало (причем смысла в этих действиях никакого нет, в отличии например от типов или какого-то явного описания, вы просто боретесь с фреймворком), либо не приходится. Речь просто о том, что стандартный сценарий использования сломан.


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

                                                                                                                                                        +3

                                                                                                                                                        Я бы исправил пример: Разработчики автомобиля решили, что вы можете случайно уехать на машине без жены, поэтому машина не поедет, пока справа от водителя не будет сидеть человек. При этом если вам нужно будет поехать одному, придётся класть груз на правое переднее сиденье.

                                                                                                                                                          0

                                                                                                                                                          Очень типобезопасность напоминает :) Когда разработчики библиотеки решают, что я случайно могу передать значение не того типа, которого они ожидают. При этом если мне вообще ничего не надо передавать, приходится делать какой-то null object или передавать undefined

                                                                                                                                                            +1
                                                                                                                                                            Очень типобезопасность напоминает :)

                                                                                                                                                            Никак не напоминает. В случае с типами вам не надо ничего делать — если ф-я ожидает, например, число, и вы суете туда число, то это just works.


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

                                                                                                                                                            А это уже как раз из разряда неявного поведения. Дело вкуса. Мы обсуждаем другой кейс.


                                                                                                                                                            Вот еще пример (как раз близкий к "случайно передать не то") — это история с getDerivedStateFromProps и prevProps. Иметь возможность обратиться к prevProps — это вполне стандартный сценарий использования данной ф-и, он нужен очень часто. Но его не добавили. Не добавили почему? Потому что при первом рендере prevProps = undefined и это могло бы кого-то смутить. Теперь все вынуждены для данного кейза дублировать пропсы в стейт.


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


                                                                                                                                                            Ну это уже не говоря о том что вообще сделали getDerivedStateFromProps статик методом из-за чего ее стало крайне неудобно использовать в принципе. А статик методом она сделана почему? Чтобы нельзя было из метода обратиться к текущим пропсам, все верно :)


                                                                                                                                                            Причем был работающий componentWillReceiveProps, который делал свою работу и всех устраивал. Кроме пары людей с квадратно-гнездовым способом мышления :)


                                                                                                                                                            К слову, в других фреймворках (всякие ангуляры, вуе, исчезающие свелте и даже прочие, не к ночи будут понмянуты, $mol) таких проблем просто не стоит.

                                                                                                                                                              +2

                                                                                                                                                              ЕМНИП, они убрали componentWillReceiveProps ради concurrentMode. Просто потому что при асинхронном рендеринге может быть выкинуто несколько "фреймов" компонента и prevProps "отстанут" на несколько циклов рендеринга. Т.е. результат componentWillReceiveProps будет зависеть от того насколько тормозит рендеринг. А это уже дичь какая-то.


                                                                                                                                                              Еще в угоду concurentMode они пожертвовали корректностью работы библиотек, основанных на синхронных подписках. Как Redux и MobX ага =)


                                                                                                                                                              Хотя в целом, я с вами согласен. Завтраками с concurrentMode они кормят нас уже два года. Со стороны ситуация выглядит абсурдно — фичи еще нет, а люди от нее уже страдают =) И вообще не очевидно, будет ли от этого реальный профит. А не только красивые презентации на конференциях.

                                                                                                                                                                0

                                                                                                                                                                А что даёт concurrentMode?

                                                                                                                                                                  0

                                                                                                                                                                  Вот тут наглядно показывают. В двух словах: если рендеринг какого-то поддерева компонентов занимает неприлично много времени, то ему можно назначить низкий приоритет. И остальной инрерфейс не будет тормозиться.

                                                                                                                                                                    0

                                                                                                                                                                    А, квантование вычислений. Насколько я понимаю, вычисление рендер-функции всё же синхронное, так что MobX ломаться не должен.

                                                                                                                                                                      +2

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

                                                                                                                                                                        0

                                                                                                                                                                        И не вызывается никакого колбэка когда компонент выкидывается?

                                                                                                                                                                          0

                                                                                                                                                                          Вызывался бы — не было бы проблемы.

                                                                                                                                                                  0
                                                                                                                                                                  Просто потому что при асинхронном рендеринге может быть выкинуто несколько "фреймов" компонента и prevProps "отстанут" на несколько циклов рендеринга.

                                                                                                                                                                  Так с getDerivedStateFromProps проблема остается — если компонент должен отслеживать изменения пропсов, а они пропускаются.
                                                                                                                                                                  Нормальным решением была бы возможность для компонента указать, должен ли он работать в concurentMode (по дефолту — нет, по крайней мере первое время для сохранения обратной совместимости) либо не должен (если нам нужен четкий контроль). Но у фейсбука как обычно, да :)

                                                                                                                                                            0

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

                                                                                                                                                    +2
                                                                                                                                                    Сейчас Парахин, например, очень активно в технологической стандартизации участвует и лично вникает в детали

                                                                                                                                                    Он уже покинул компанию. Так что его методы работы явно не история успеха.


                                                                                                                                                    Что вас привлекает в React?

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


                                                                                                                                                    В частности обновление view при обновлении model (из за чего мы и имеем пляски с Redux, MobX, т.п.).

                                                                                                                                                    Не могу на эту тему дискутировать, в моих проектах достаточно нативного setState, работает без проблем, велосипед изобретать не приходится (Мы пишем UI-библиотеку).


                                                                                                                                                    Vue а так же добавили биндинги вроде onkeypress.enter или onclick.preventdefault, что мелочи, но сразу показывает, что они в теме, так как это очень частые операции

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


                                                                                                                                                    Сравните с навешиванием событий в React, когда до стрелочных функций приходилось писать bind в конструкторе на каждый обработчик

                                                                                                                                                    В до-es6 времена был React.createClass, в котором все методы автоматически байндились к this, это в версии на es6-классах эту функциональность убрали, потому что появился удобный нативный синтаксис.


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

                                                                                                                                                    Понятно. Так и Redux эту природу не нарушает. Мы же не используем connect в каждом компоненте, а только там где нам нужны глобальные данные. Что именно должно отправиться в глобальный стор, а что остается локально – отдельный хороший архитектурный вопрос.


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

                                                                                                                                                      –1
                                                                                                                                                      Как по мне, грамотный тимлид подскажет как правильно приготовить Redux, а не будет авторитарно его запрещать. Кстати, а если не Redux, то что использовать взамен?

                                                                                                                                                      1) Тимлид увы не всегда грамотный и/или они грамотный но, для людей который схожи по мышлению с ним.
                                                                                                                                                      2) Если не Redux, то MobX. А ещё лучше, если не MobX то что? Ничего, лучше ничего не придумано.
                                                                                                                                                        0
                                                                                                                                                          –3
                                                                                                                                                          Хватит уже эту дичь втирать и толкать)))
                                                                                                                                                            +2

                                                                                                                                                            Это не дичь, а более продвинутая система реактивности, чем в MobX.

                                                                                                                                                              –1
                                                                                                                                                              я и говорю дичь.
                                                                                                                                                                0

                                                                                                                                                                Чем она более продвинута-то? Тем, что одна и та же функция используется как для чтения значения, так и для записи?..

                                                                                                                                                                  0

                                                                                                                                                                  Двусторонний поток данных.
                                                                                                                                                                  Абстракция от асинхронности.
                                                                                                                                                                  Контроль времени жизни значения.
                                                                                                                                                                  Человекопонятные идентификаторы.
                                                                                                                                                                  Во вторых атомах поддерживается квантование вычислений.

                                                                                                                                                                    +2

                                                                                                                                                                    Не для всех двусторонний поток данных однозначное "лучше". А с человокопонятностью в $mol ві пошутили? Что $ значит у вас я уже не понимаю :)

                                                                                                                                                                      0

                                                                                                                                                                      Не все способны спроектировать простую надёжную и гибкую архитектуру. И что?


                                                                                                                                                                      Не пошутил.


                                                                                                                                                                      Это префикс глобалных неймспейсов.

                                                                                                                                                                        0

                                                                                                                                                                        Ну вот односторонний поток данных и является простым. Двусторонний обмен сложнее концептуально.


                                                                                                                                                                        Вы не помните критики ваших примеров в топиках типа этого? По памяти, люди, разработчики здесь на Хабре, очень часто советуют вам сделать DX при работе с $mol проще и понятнее. Прежде всего в плане читаемости.


                                                                                                                                                                        А зачем? На него логика какая-то завязана? И они реально глобальные?

                                                                                                                                                                          –1

                                                                                                                                                                          Да нет, двусторонний как раз проще. Забиндил одно свойство на другое и всё работает. Без свистоплясок с экшенами, событиями и прочими стримами.


                                                                                                                                                                          А какие именно там проблемы с читаемостью? И какое она отношение имеет к генерации идентификаторов из имён заданных прикладным программистом?


                                                                                                                                                                          Реально глобальные. На них сборка завязана.

                                                                                                                                                                            +1

                                                                                                                                                                            Это пока не нужно выяснить, а почему вот это свойство имеет неожиданное значение. С однонаправленным "биндингом" мы всегда знаем откуда оно пришло и легко можем определить где оно изменяется в принуципе (особы хардкор динамический языков в расчёт не беру), с двусторонним где угодно может оказаться биндинг и значение присвоено не искомой перемнной а сбинженной, возможно не на первом уровне, а по длинной цепочке.


                                                                                                                                                                            А чего не сделать было человекочитаемый префикс типа global_?

                                                                                                                                                                              0

                                                                                                                                                                              https://github.com/nin-jin/slides/blob/master/orp/readme.md#%D0%B4%D0%B2%D0%B8%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85


                                                                                                                                                                              И везде писать global_mol_mem вместо $mol_mem? Такое себе удовольствие.

                                                                                                                                                                                +2

                                                                                                                                                                                Просто mol_mem? А лучше MolMem?

                                                                                                                                                                                  –1

                                                                                                                                                                                  У вас аллергия на баксы или что? Доллар замечательно позволяет отличать локальные имена и глобальные. На всякий случай — имена есть не только у переменных, но и у полей объектов, методов и пр.


                                                                                                                                                                                  PascalCase ни чем не лучше: https://github.com/eigenmethod/mol/issues/312

                                                                                                                                                                                    +2

                                                                                                                                                                                    У меня аллергия на нарушение общепринятых соглашений. С аллегрией на "бакс" я не смог бы писать на PHP скоро как половину жизни.


                                                                                                                                                                                    Так уж сложилось, что общепринятым в экосистеме JS является именнование конструкторов/класов в PascalCase, а переменных, параметров и членов клаасов в camelCase.


                                                                                                                                                                                    И в целом не понимаю необходимости отличать локальные имена от глобальных. Наличие имён $name и name в одном скоупе в любом случае допускает их смешение хоть при написании кода, хоть при чтении. А если такого наличия нет, то префикс избыточен.

                                                                                                                                                                                      0

                                                                                                                                                                                      Зачем нужно именно такое именование можете почитать тут: https://habr.com/ru/post/456288/

                                                                                                                                                                                        +2

                                                                                                                                                                                        Понятно зачем — чтоб облегчить "понимание" кода программой. Оказывается, это расширенный стиль, которы я называю Zend_Loader_Autoloader style.


                                                                                                                                                                                        То есть это не человекочитаемый код, а машиночитаемый. Не для человеков ведь этот префикс, а для машин.

                                                                                                                                                                                          –1

                                                                                                                                                                                          Он для одинакового понимания как человеком, так и машиной в любом контексте.

                                                                                                                                                                  +2

                                                                                                                                                                  Вот сделали бы сравнение React+MobX vs React+$mob_atom — может народ бы и понял, что второе круче.

                                                                                                                                                                    +1

                                                                                                                                                                    Тут сам реакт мешает многим плюшкам.

                                                                                                                                                                      +1

                                                                                                                                                                      То есть для реакта лучше не придумано всё-таки? :)