За что я не люблю Redux +22


AliExpress RU&CIS

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

Flux - это вовсе не что-то новое либо революционное

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

В начале нулевых я разрабатывал ПО и библиотеки компонент на Delphi под Windows (сначала Win9x, потом XP). В операционных системах Windows с самых первых, если не ошибаюсь, версий, для визуальных элементов интерфейса (кнопки, поля ввода) существует понятие окна - да, окно это не только то, что с рамкой, почти любой визуальный элемент управления имел свое собственное окно. Окно в данном случае - это некая структура в памяти, которая имеет ассоциированный с ним идентификатор (window handle) и оконную функцию (см. далее). Если мы хотим выполнить какое-либо действие над элементом, например - изменить текст кнопки, мы должны упаковать это действие в специальную структуру-сообщение (Window message) и отправить ее соответствующему окну. Структура состоит из закодированного типа сообщения (например WM_SETTEXT - для установки текста) и собственно payload. Будучи отправленным, сообщение не попадает в обработчик напрямую - вместо этого оно отправится в очередь, из которой его извлекает некий диспетчер и вызывает оконную функцию того окна, в которое мы сообщение отправили, передав его в виде параметра. Оконная функция в простейшем случае - это большой switch, где в зависимости от типа сообщения мы передаем управление более конкретному обработчику. Ничего не напоминает?

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

Нарушение принципа "Low coupling, high cohesion"

Если вы ищите простую и понятную формулировку, что такое качественный дизайн, то эти четыре слова из подзаголовка коротко и емко его описывают - внутри модуля или компонента его элементы должны быть тесно связанны друг с другом, в то время как связи между отдельными модулями/компонентами должны быть слабыми. Это базовая ценность. Все остальные принципы и подходы в проектировании - следствия из этого принципа. "Low coupling, high cohesion" отвечает на вопрос "чего мы хотим добиться", в то время как, скажем, SOLID-принципы или любой из Design Pattern указывает нам "как мы можем этого добиться".

И вот тут Redux подводит - то, что должно быть цельным внутри компонента, оказывается размазанным по множеству файлов и сущностей - получаем Low cohesion вместо High. Связи, которые должны оставаться внутри, выходят наружу. Если нарушение принципа Low Coupling обычно представляют себе в виде переплетений из лапши, то здесь у меня в голове всплывает другое кулинарное блюдо. Позаимствовав терминологию у Java-разработчиков, если отдельный компонент - это фасолинка (Bean) - цельная, замкнутая вещь в себе, то тут мы получаем что-то вроде рагу, где фасоль полопалась и его содержимое вытекло, образовав густую однородную кашу, обволакивающую всю систему целиком, и не позволяющую на нее смотреть как на композицию отдельных законченных и слабо-зависимых сущностей.

Множество Boilerplate кода

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

Неуместное использование

А еще мне не нравится, что Redux или схожие с ним инструменты пытаются использовать там, где они не нужны - скажем, в Angular (angular-redux, NgRx). Redux предназначен для решения проблемы передачи данных в компоненты путем использования глобального State, и в React.js действительно существует такая проблема, там его использование кажется уместным. Но в Angular такой проблемы нет, Injectable-сервисы прекрасно справляются с этой задачей. Зачем решать несуществующую проблему, порождая при этом новые (о которых было написано выше)?

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

В заключение надо бы отметить и что-нибудь хорошее. Допустим, это не так плохо, когда у вас большая команда разработчиков разного уровня, и все пишут понятный всем код примерно в одном стиле ничего не выдумывая. Если иначе такая разношерстная команда не сможет работать эффективно, значит овчинка выделки определенно стоит. Но на самом деле хотелось бы иметь простое и эффективное решение, лишенное вышеназванных недостатков. Context API? Может быть.

Теги:




Комментарии (76):

  1. dopusteam
    /#23166760

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

    О чем речь вообще?

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

    О чем конкретно речь?

    инструменты, направленные на решение этой проблемы, существуют, но как по мне - не решают ее полностью.

    Почему не решают? Какие инструменты?

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

    Это проблема инструмента?

    Но в Angular такой проблемы нет, Injectable-сервисы прекрасно справляются с этой задачей

    Скорее уж rxjs, injectable и стейт так себе связаны, Вы точно понимаете о чем речь?

    • pharrell
      /#23167546 / +1

      Injectable — часть системы Dependency Injection, которая в свою очередь имеет IoC Container, который в свою очередь является глобальным состоянием приложения.
      А вот RxJS тут как раз ни при чём:)

      • nin-jin
        /#23167808

        В Ангуляре на самом деле используется дерево контекстов (Injector), а не один глобальный контейнер.

      • dopusteam
        /#23167822

        А вот RxJS тут как раз ни при чём:)

        Все стейт менеджеры на ангуляре основаны на rxjs, даже если Вы свой будете делать - это будут сервисы с rxjs

        IoC Container, который в свою очередь является глобальным состоянием приложения

        Что? Есть ссылки, подтверждающие это?

        • nin-jin
          /#23167868

          MobX не основан на RxJS. Хотя и прикручивается через недокументированные костыли.

        • saaivs
          /#23169840 / +1

          Что? Есть ссылки, подтверждающие это?

          Собственно, сама документация angular.io/guide/dependency-injection
          Никакого отношения Angular DI сам по себе к rxjs не имеет.

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

          Вот, например, одна из его standalone имплементаций ( от одного из представителей Angular Core Team) www.npmjs.com/package/injection-js, которую можно использовать где-угодно и там явно видно, что никаких внешних зависимостей(кроме tslib) у реализации DI нет.
          На основе подобной библиотеки можно строить свои фреймворки, к Angular отношения не имеющие.

          • dopusteam
            /#23170678

            Собственно, сама документация angular.io/guide/dependency-injection

            Я там про состояние ничего не увидел

            Никакого отношения Angular DI сам по себе к rxjs не имеет.

            Я обратного не утверждал. Я не согласен с идеей, что «ангуляру не нужен redux т.к. в ангуляре есть DI», изначально как то так звучала мысль

            С остальным я согласен, да в общем и не спорил

            • saaivs
              /#23171200

              Я там про состояние ничего не увидел

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

              Мысль, что «ангуляру не нужен redux т.к. в ангуляре есть DI» странна сама по себе. DI — это про управление зависимостями. Redux — про управление потоками данных. DI для angular — это фундамент, поверх которого он построен.
              Redux — как способ организации потока данных абсолютно опционален. Он не нужен(или нужен) не потому, что есть DI, а потому, что есть масса и других способов организовать управление состоянием хоть с использованием DI, хоть без него.

              • dopusteam
                /#23171338

                Состояние — это просто область памяти специфического назначения

                Ну это уже демагогия пошла. IoC контейнер всё ещё не является 'состоянием' в общем смысле.

                Мысль, что «ангуляру не нужен redux т.к. в ангуляре есть DI» странна сама по себе

                Ну так мысль то не моя, я изначально про неё и высказался, в оригинале

                Redux предназначен для решения проблемы передачи данных в компоненты путем использования глобального State… Но в Angular такой проблемы нет, Injectable-сервисы прекрасно справляются с этой задачей


                Я нисколько не топлю ни за redux ни против, более того — я им даже не пользуюсь

                • saaivs
                  /#23171662

                  IoC контейнер всё ещё не является 'состоянием' в общем смысле.

                  О чём и речь.

            • YSpektor
              /#23171280

              Я не согласен с идеей, что «ангуляру не нужен redux т.к. в ангуляре есть DI», изначально как то так звучала мысль


              Ээ, нет, мысль звучала не совсем так

              • dopusteam
                /#23171322

                Redux предназначен для решения проблемы передачи данных в компоненты путем использования глобального State… Но в Angular такой проблемы нет, Injectable-сервисы прекрасно справляются с этой задачей

                Вот же, нет?

                • YSpektor
                  /#23171404

                  Все верно, только здесь написано не так, как меня «произвольно процитировали». Написано что:
                  1) Redux решает проблему передачи данных в компоненты, в случаях где нам неудобно/невозможно/нерационально использовать пропсы
                  2) В Angular аналогичную задачу принято решать с использованием сервисов, объявляемых с помощью Injectable (и соответственно через механизм DI внедряемых в компоненты — это не написано, но действительно подразумевается)
                  Здесь не написано что DI это замена Redux, но возможно мне нужно четче формулировать свои мысли

    • AxisPod
      /#23172000

      1. Явный троллинг

      2. Ещё более явный троллинг

      3. Опять же сродни троллинга

      4. Это проблема API и ещё какая. Если уж инструмент не предназначен для чего либо, то и желательно как-то ограничить API. Опять же документация и внятное описание для решения каких проблем инструмент подходит. Топором тоже можно забить гвоздь, но ведь молотком удобнее.

      5. Видимо понимает и ещё как. Делается отдельный сервис хранилище, отвечающий за конкретные данные. И пользуйтесь им на здоровье, в совокупности c RxJS вообще будет отличное решение. Да при этом данное решение ещё и легко тестируется.

      • MaZaAa
        /#23172088

        в совокупности c RxJS вообще будет отличное решение.

        Для тех, кто любит когда кровь из глаз течёт глядя на такой код да, вообще отличное решение :D
        А если ещё и придётся через недельку другую к этому коду вернуться и что-то там пофиксить или добавить фичу, вообще сказочное самовозгорание произойдет :D

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

  2. MaZaAa
    /#23166844 / -2

    Но на самом деле хотелось бы иметь простое и эффективное решение, лишенное вышеназванных недостатков. Context API? Может быть.

    Серьезно?) Вы не знаете?) MobX разумеется ваше лекарство (и моё тоже).

    • sergeymolchanovsky
      /#23167350

      Заминусовали тут бедолагу.
      MobX классная, интуитивно понятная штука.
      Во Флаттере тоже его юзали, целый проект на нем написали, и очень довольны. Сейчас перешли на GetX (умеет все то же самое + не тратится время на кодогенерацию + не зависит от контекста + круто оптимизирован вплоть до апдейта отдельных обсерверов по тегам), вообще всем рекомендую.

  3. Fen1kz
    /#23166866

    Я постоянно пишу прототипы игр на js, хобби у меня такое. И как-то решил перейти на ts, а на нем мне стало что-то трудно сделать redux+thunk стек, плюс похожих статей начитался и решил забить на redux. Жили же без него и будем жить.


    В итоге сделал, значит, кучу классов, Game, Entity, сделал Game.processTurn, на всякий случай выделил GameState чтобы жил отдельно. Для контроля за игрой сделал систему ивентов, чтобы entity сами решали, что они будут делать. Пара часов и вуаля, у меня есть базовая система ивентов, где мы высылаем "ивент", его ловят "ентити", у которых есть набор обработчиков на интересующие их ивенты.


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


    Когда у меня получилось что-то вроде:


    Game.ts:
    ...
    this.fireEvent('attack', ...)
    ...
    
    BaseFighterEntity.ts:
    this.eventMap = {
      move: (gameState, entityState) => {
        ...
        return newGameState;
      }
      attack: (gameState, entityState) => {
        ...
        return newGameState;
      }
    }

    Сижу я такой, довольный собой, вроде всё работает, удобно и без этого вашего redux, waaait a second, и вот тут до меня доходит, что же я наделал.


    Программиста можно вытащить из redux, а redux из программиста уже нет.

    • dagen
      /#23167656

      Ну вы палку перегибаете. Это всё в минималистичном backbone.js из коробки есть, и при этом backbone.js никому не приходит в голову называть ридаксом. А похожие паттерны везде используются, на то они и паттерны, верно? Паб/саб, диспетчер-медиатор - это стандартные широко используемые штуки.

      • Fen1kz
        /#23168138

        Если не ошибаюсь, пабсаб предполагает свободную подписку/отписку на каналы событий и отдельные, изолированные стейты подписчиков, которые не меняют общий глобальный стейт

        • dagen
          /#23170228

          Есть подозрение, что ридаксовский стор (которых можно понаделать столько, сколько вам угодно), который вы называете общим глобальным стейтом, и есть тот самый подписчик. А диспатчер, который медитор — это и есть тот самый канал.

          • Fen1kz
            /#23171320

            Только там store.subscribe это не "стор может подписаться на что-то", а "подписать любой другой листенер на стор"

  4. funca
    /#23167028 / +3

    Вы правы в том, что принцип взаимодействия, основный на сообщениях "message-based", не нов. Но он настолько абстрактен (широк), что под него попадает куча всего разного: устная и письменная речь, голубиная почта, комментарии на Хабре, IP protocol, Http, ReST, упомянутый вами winapi - список можно продолжать до бесконечности. Принципиальные отличия, которые обусловливают применимость в том или ином случае, находятся в деталях.

    По-моему основная заслуга flux в том, что он из конкретной технологии, которой пользовались дорогие годы PHP'шники (http, stateless server, database), сформулировал своеобразный абстрактный архитектурный принцип. Это позволило создать новые подобные решения, включая redux, для использования в других областях.

    Сам по себе redux тоже довольно абстрактен - его можно "готовить" по-разному, и это создаст основные проблемы разработчикам. Например, один из альтернативных вариантов предлагает воспринимать действия "actions" не как команды (намерения) что-то сделать в будущем, а как события "events", т.е. информацию о том что уже случилось в прошлом. В этом есть определенная логика. Что случилось, то случилось и это уже нельзя отметить. Можно лишь сделать какие-то выводы (reducers) и где-то записать (state). Подобные соглашения снимают массу вопросов при разработке, но требуют определенной дисциплины, которую не понятно как формализовать, чтобы автоматически обнаруживать несоответствия в коде. Это делает такие решения довольно уязвимыми к ошибочным изменениям, что может быть так же причиной критики redux.

    Redux хорошо уживаются с другими event-based паттернами, например Event Sourcing (одним из применений которого является пресловутая time machine, позволяющая проигрывать историю изменений в любой момент времени). Согласитесь, это совсем не похоже на то, как используют winapi.

    • YSpektor
      /#23168634

      Согласитесь, это совсем не похоже на то, как используют winapi.

      Вы рассуждаете с точки зрения поведения системы, а я — с точки зрения ее структуры. По поведению вопросов нет. А по структуре от того, как использовали WinAPI, как по мне, ушли не очень то и далеко.

  5. sergeymolchanovsky
    /#23167342

    Гребаный стыд — юзать Redux в таких продвинутых движках, как Flutter. Где есть значительно более подходящие паттерны стейт-менеджмента, заточенные специально под этот фреймворк.
    Но тем не менее, до сих пор во всяких корпорациях его применяют, что хуже — еще и гордятся этим. Печально видеть, когда компания движется по пути наименьшего сопротивления «для ускорения кодинга».

    • Alexufo
      /#23167584

      так пакет этот туда залили как раз те кто с реакта и перебегает.

  6. andreyverbin
    /#23167344

    Сравнение redux и win API это очень метко, у меня на один аргумент для споров стало больше. Жаль только, что множество молодых разработчиков не испытали на себе все это и не поймут всю боль. Возможно поэтому мы и наступаем на одним и те же грабли раз за разом.

  7. AGrinko
    /#23167400

    Хорошо изложено. Согласен насчёт boilerplate-кода - это прямо беда.

    И вот тут Redux подводит - то, что должно быть цельным внутри компонента, оказывается размазанным по множеству файлов и сущностей - получаем Low cohesion вместо High. Связи, которые должны оставаться внутри, выходят наружу

    Вот с этим не могу согласиться. Основная идея центрального хранилища в том, чтобы обеспечить единый источник информации (source of truth), которая нужна в разных компонентах или даже в разных модулях. Redux отлично подходит для глобального стейта. Он также вполне позволяет изолировать часть состояния и его логику на уровне модуля. Ну а если какая-то логика и состояние нужны только в одном компоненте - используйте для этого внутренний стейт компонента. Не нужно всё локальное пихать в store - это и сам Дэн Абрамов, по-моему, советовал.

    • JamesJGoodwin
      /#23167750

      Жаль, что про Redux-toolkit в основном либо не слышали, либо не пробовали. И ведь статей хватает что на Хабре, что на Медиуме.

      • JustDont
        /#23168170

        Тут проблема в самой постановке. Добавим на redux сверху redux-toolkit, это уже практически столько же пожатого js, сколько одна mobx — и это просто для того, чтоб редаксом можно было пользоваться без боли… везде.

        • MaZaAa
          /#23168176

          Все так же с болью, просто боли будет чутка поменьше.

        • JamesJGoodwin
          /#23169986

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

          В этих делах важно найти золотую середину и redux-toolkit в этом случае как раз помогает перейти от чего-то что "так себе" к чему-то что "норм" без значительных потерь.

          • MaZaAa
            /#23170148

            Вы серьезно не знаете что такое MobX? В чем смыл рассуждать об откровенно слабых и ущербных полумерах в виде redux-toolkit, когда уже давно существует по настоящему правильное и хорошее решение?

            • JamesJGoodwin
              /#23170272

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

              • MaZaAa
                /#23170878 / -2

                Я рассуждаю о том, что видел в использовании в рамках крупных проектов и о том, чем пользовался сам.

                Вы имеете ввиду древнее легаси, от которого воняет за километр. И не надо пытаться защищать такие проекты с точки зрения разработчика, это абсурдно. Топтаться годами на месте и тем более не смотреть по сторонам, не знаю какие есть инструменты, не пробуя их — тупиковый путь. Работая на таких проектах, вы автоматически отстаете от мира лет на 5. Про сильнейшую потерю навыков проектирования архитектуры и т.д. и т.п. я вообще молчу.
                Про MobX мне действительно мало известно

                Ахахах, жесть, в 2021 году слышать такие слова нелепо.
                Очень странно, откуда вы тогда вообще про React слышали? Это же технология из нашей эры. К сожалению не удивительно тогда почему вы думаете что redux-toolkit это «норм».
                но радикализм в выборе технологий осуждаю.

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

                • nin-jin
                  /#23171634 / +1

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

                  • MaZaAa
                    /#23171752

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

                    Кто сказал? Я пробовал всё из актуального, Vue (v2 и v3), Angular, Svelte, Flutter, React, Preact, Inferno и т.п. и лично для меня на сегодняшний день связка React + MobX является лучшей:
                    1) Cправляются со всеми моими проектами и задачами более чем достаточно.
                    2) Не связывают мне руки.
                    3) Дают легко читаемый, легко развиваемый и поддерживаемый код. Конечно если уметь его писать, если не уметь, то будет говно всегда)

                    Ваш любимый $mol не пробовал и не при каких обстоятельствах даже пробовать не буду, там настолько отвратительный синтаксис что мама не горюй. Путь он хоть будет работать в 100 раз быстрее реакта, будет в 1000 раз эффективней и т.п., всё равно из-за синтаксиса ни за что его не возьму.

                    Итого: для меня сейчас нету ничего лучше React'a + MobX.

                    • Alexandroppolus
                      /#23171952

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

                      Я вот подозреваю (хотя нельзя сказать наверняка), что в $mol есть прорывные идеи. Но, увы, банально из-за синтаксиса он никогда не взлетит, даже если его будет пропушивать какая-нибудь корпорация.

                    • nin-jin
                      /#23172040

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

                      А малину даже пробовать не станете так как у неё форма странная и вся в пупырышках.

                      • JustDont
                        /#23172224

                        В идеальном безкомпромиссном мире я бы возможно когда-нибудь и попробовал ваш $mol. В реальном — я даже начинать не буду, потому что уже даже со Svelte есть определенные сложности по поводу объяснения её другим людям, когда вам нужен +1 программист на проекте или просто другой программист взамен вас.
                        И в этом смысле реакт прекрасно попадает в зону компромисса, Svelte — близок к ней, а $mol находится от неё настолько же далеко, насколько, скажем Idris от С++.

                        • nin-jin
                          /#23173366

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

                          • MaZaAa
                            /#23173396

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

                            Вы путаете.
                            Дело не только в эффективности, дело в совокупности всех факторов.
                            А касаемо $mol, вам же сто раз уже говорили, что по совокупности факторов он не пригоден для использования(из-за адского синтаксиса), и не важно насколько он эффективный и быстрый.

                            Если брать голую эффективность и производительность, то React это достаточно ущербная штука. Но если взять React + MobX, то по совокупности всех факторов и по сравнению со всеми остальными альтернативами, получается лучший вариант на сегодняшний день.

                          • JustDont
                            /#23173422

                            Что такое, стрелочка не поворачивается?

                            Синтаксис у вас ущербнейший, это факт. И нет никаких оснований, почему он должен быть совершенно нечитаем, кроме как вашего "ну он только таким и должен быть, честно!".


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


                            В сухом остатке имеем отличную технологию для протаскивания куда-нибудь в важное место тихой сапой в попытке стать незаменимым работником. А для адекватного использования — всё разбивается об то, что 9 из 10 фронтэндеров смотрят на это и говорят "ну и зачем это тут, уберите". А из оставшихся — еще 9 из 10 смотрят чуть дальше, и им становится плохо от синтаксиса и от запредельной местячковости всего проекта. А из джунов и вовсе 10 из 10 не хотят на это смотреть, потому что это не marketable skills.

                            • nin-jin
                              /#23173438

                              Синтаксис у вас ущербнейший, это факт.

                              Докажите.

                              • JustDont
                                /#23173498

                                Это субъективная оценка, какое доказательство вы хотите тут видеть? И да — это факт, что для меня синтаксис $mol ущербнейший.


                                Впрочем, кое-какой небольшой анекдотичный опыт у меня собран: в общей сложности я навёл на $mol (среди прочих) с середины 2019 года шестерых коллег на двух разных работах и проектах — на одном нужен был выбор с чистого листа, на другом — можно было сменить реакт. До усечения выборки по критериям применимости к ситуации: 6/6 были готовы работать с реактом. 4/6 были готовы работать с ангуляром. 2/6 были готовы возиться с вебкомпонентами. 1/6 был готов на svelte. 0/6 захотели $mol.

                                • nin-jin
                                  /#23173710

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

                                  • JustDont
                                    /#23173716

                                    Так в чём проблема? Почему вы всё еще не стали Фордом современности, и не отправили всех этих отсталых на пенсию?

                                    • nin-jin
                                      /#23173806

                                      Борьба с луддизмом — процесс не быстрый, да и не особо увлекательный.

    • mayorovp
      /#23168448

      Вот с этим не могу согласиться. Основная идея центрального хранилища в том, чтобы обеспечить единый источник информации (source of truth), которая нужна в разных компонентах или даже в разных модулях

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

    • YSpektor
      /#23168456

      Вот с этим не могу согласиться. Основная идея центрального хранилища в том, чтобы обеспечить единый источник информации (source of truth), которая нужна в разных компонентах или даже в разных модулях. Redux отлично подходит для глобального стейта.

      Ну, с этим даже глобальные переменные справятся (ладно, утрирую, нужен еще какой-то Pub/Sub). В чем смысл, если нарушается инкапсуляция данных, принцип Single Responsibility? Singleton-сервис + Dependency Injection и задача решена без лишних сложностей.

  8. Dron007
    /#23167632

    Лично меня больше всего в Redux напрягает то, что селекторы не являются его частью. Это ведь общая система, как СУБД и удобно когда рядом с СУБД лежат и хранимые процедуры или VIEW, который знает всё об организации хранения данных и позволяет другим частям абстрагироваться от этого, что уменьшает число дублирующегося кода, ошибок, упрощает рефакторинг в случае необходимости. Такой себе фасад. Настрочили на Reselect кучу этих селекторов, всё хорошо, но как дебажить? Они нигде не видны.


    Схожая ситуация с эффектами, которые у нас на сагах организованы. Хочется видеть где-то всех участников: экшны — редьюсеры — саги — селекторы.


    Другой момент, который может больше к Реакту относится — пихаемая где надо и не надо декларативность. Ну вот не везде она нужна. Сколько раз было, что мне надо ловить именно событие, а не состояние. И в итоге приходится извращаться и отслеживать какую-нибудь смену статуса видимости для показа модалки.

    • boolive
      /#23167706

      Селекторы на Reselect — лишний слой. Возник из-за бардака в структуре состояния. Имеем дело с "состоянием приложения", а не базой данных. Состояние нужно быстро, просто напрямую использовать без всяких трансформаций и заметаний следов к источнику. PS Саги для извращения логики. :)

      • Dron007
        /#23167724

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

    • YSpektor
      /#23168464 / +1

      Это ведь общая система, как СУБД

      Ой, а вот это мне совсем не по душе. Вы в случае СУБД что, SQL-запросы привыкли вызывать прямо из Presentation-слоя?

      • Dron007
        /#23169138

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

        • YSpektor
          /#23169182

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

          • Dron007
            /#23169386

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


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

            • YSpektor
              /#23169622

              А, я Вас понял теперь, совершенно не то представлял, когда писал предыдущий комментарий. Спасибо за подробное объяснение, здесь я с Вами согласен, все, что изолирует ui от внутреннего устройства данных - это хорошо

  9. boolive
    /#23167682

    redux можно приготовить без boilerplate-кода, без middleware (thunk, saga..) и вообще без кучи типов действий. Останется простой менеджер состояний без ваших минусов. То что вы сами изобретете, отказавшись от redux.

  10. i360u
    /#23167880

    На мой скромный взгляд, основная проблема Redux, в том, что он реализует простую вещь каким-то очень вычурным способом, какой мог родиться только в мозгу глубоко пораженном функциональным программированием. Я, ни в коем случае, не говорю сейчас, что ФП, само по себе, это плохо. Я говорю о том, что ФП — как набор неоспоримых догм и религия, там где это уместно и неуместно — это путь в ад. Любители умного слова «иммутабельность», вы вообще в курсе как в JS устроена работа с памятью? Я думаю, когда создатели редакса сами поняли как облажались, они переориентировали свой маркетинг на возможность откатывать изменения и дебажить «во времени». Проблема только в том, что понадобиться это может в очень незначительном количестве кейсов, да и там это можно было бы реализовать лучше. Любой, кто когда-либо писал свой простенький велосипедный pub/sub, поймет о чем я. Как вообще этот трэш смог стать таким популярным? Вообще, конечно, я знаю как. Но ответ многим не понравится.

    • YSpektor
      /#23168480

      Спасибо, те же ощущения, вы хорошо сформулировали то, что у меня сформулировать не получилось (насчет «дебажить во времени»)

      Вообще, конечно, я знаю как.

      А мне, кстати, любопытно

    • Alexandroppolus
      /#23169086

      Как вообще этот трэш смог стать таким популярным?

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

      • JustDont
        /#23169250

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


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

        • noodles
          /#23171518

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

          Когда работал в аутсорсинге — два раза кидали на крупные проекты, где буквально была одна долгосрочная основная задача — переписывание с redux на mobx..)) ибо дальше видимо было невозможно с этим жить и развивать)

          • JustDont
            /#23171546

            Так конечно, я вот тоже переписываю один.
            Но есть и множество тех, которым "и так норм".

          • nin-jin
            /#23171646

            Меня однажды заставили переписать проект в обратном направлении ибо команда не осилила "магию мобх".

      • MentalBlood
        /#23173634

        Жизненно. Как то проходил на известном иностранном ресурсе курс курс по реакту, там тоже редукс потом добавляли. Выглядело это мянко говоря нелепо, куча бойлерплейта ради простейших задач.
        Правда, у меня был бэкграунд (много C, солидный проект на C++, поделки на Python). Но вроде и без него должно быть видно, что редукс нужен только в очень сложных или специфичных проектах

  11. kotovsky_art
    /#23168190

    Вы видимо не разобрались или не умеете его готовить. UDF архитектура - одна из самых слабосвязанных и легкотестируемых архитектур.

  12. boldMahoney
    /#23168192

    В полабзаца расписал, что из себя по сути представляет событийная модель и очередь сообщений в UI винды! Сто плюсцов этому господину!
    Подобное супер объяснение, но уже про коллбеки видел лишь однажды в толстенном учебнике по VBA для Excel. Респект таким, кто может на пальцах рассказывать сложные вещи просто.

  13. kubk
    /#23168422

    Но в Angular такой проблемы нет, Injectable-сервисы прекрасно справляются с этой задачей.
    Injectable сервисы нужны для того, чтобы шарить состояние между деревом компонентов. Эти сервисы никак не отвечают за оповещение компонентов об изменениях. За это отвечает Zone.js — самая глупая система оповещения изменений, которую только можно найти в современных фреймворках. Почему глупая? Потому что это monkey patching и потому что обновления компонентов не точечные. Умная система оповещения изменений знает какой компонент от какого значения зависит и обновляет компоненты точечно (Mobx / Vue).

    • YSpektor
      /#23168494

      Эти сервисы никак не отвечают за оповещение компонентов об изменениях.


      Сервисы шарят, а Observable, Subject — оповещают об изменениях

    • saaivs
      /#23169882 / +1

      За это отвечает Zone.js


      Вы ошибаетесь. Zone.js вообще не для этого.
      Концептуально это execution context только для для асинхронного кода и соответсвующего runtime, а это совсем другая история.
      Более того, он вообще опционален и приложения можно строить вообще без него.
      Умная система оповещения с точечными изменениями фреймворку вполне по силам.

  14. aio350
    /#23168444

    Современный Redux, представленный Redux Toolkit, не так уж плох. Если же говорить о небольших и средних проектах, то, действительно, Context API + useReducer() + Immer — то, что доктор прописал. А еще есть такая штука, как Recoil (покамест экспериментальная). Учитывая, что его разработкой занимается (или занимался) Jordan Walke (тот чувак, который разработал React), а также то обстоятельство, что команда React, и, в частности, Dan Abramov (тот чувак, который «разработал» Redux), в последнее время усиленно дистанцируется от Redux, можно предположить, что именно Recoil станет официальным инструментом React для управления состоянием приложений (впрочем, Walke в январе этого года ушел из Facebook, so...). Еще интересно, когда React, наконец, определится с инструментом для CSS.

    • /#23168526

      > Еще интересно, когда React, наконец, определится с инструментом для CSS.

      Я думаю, никогда. Всё-таки React официально позиционирует себя как библиотеку, а не как фреймворк

      • YSpektor
        /#23168554

        Ну, библиотека от фреймворка отличается не количеством фич из коробки, а наличием или отсутствием инверсии управления. В случае библиотеки программист сам решает где и когда ее функции вызывать, а в случае фреймворка — он дает программисту точки, к которым можно «присосаться» и кастомизировать поведение (так что утверждение что Реакт — это библиотека тоже может быть весьма спорным). В конце концов ввести в реакт Context API разработчикам ничего не помешало

  15. talerok
    /#23178498

    Жму руку автору. Ngrx/Ngsx + angular — это просто боль. Люди сами не знают зачем оно им надо, тащат в проект, просто потому что модно. Обычно этим занимаются те, кто пришел с реакта.