Comments 79
Раз уж в заголовке написано про 2024 год, то почему ни слова про Redux Toolkit? Разработчкики Редакса советуют использовать именно его, а не Redux Core.
Да что там Toolkit, в примерах даже хуков нету, код выглядит как из доковидных времен, что с Редуксом, что с Мобиксом.
Учел ваше замечание и добавил подробное сравнение в блоке Redux Toolkit и mobx-state-tree
mobx-state-tree это прям дно, примерно на одном уровне с redux, effector, rtk, zustand, reatom и прочим мусором. Только чистый MobX решает безальтернативно. Либо самописный аналог ибо больше ничего аналогичного нет из кем-то написанных и выложенных решений.
Мне вот всё не даёт покоя, что вас мотивирует столько энергии вкладывать в продвижение MobX? Научи меня, о великий мастер, черпать бездонную энергию.
С большего в том блоке сравнивается чистый Mobx (в некоторых случаях с использованием mobx-state-tree), в комментах ребята просили осветить его, поэтому добавил в таком формате
Ну тут как бы MobX без вариантов, ничего лучше для реакта нет, даже близко.
Раз
Два
Три
https://stackblitz.com/edit/stackblitz-starters-omqu6z?file=src%2FApp.tsx
Есть Effector. Понятный и простой.
Redux ... подходит для больших и сложных приложений
Mobx ... подходит для маленьких и средних приложений
Много раз видел это сравнение, и всегда - ничем не обоснованное.
Скорее всего обосновано только тем, что разработчики на редаксе не привыкли включать голову в процессе разработки и уж тем более продумывать архитектуру и вкладываться в её становление и развитие. =)
Просто любое приложение на редаксе становится большим и сложным ?
это очердной перевод западной статьи 5летней давности. Мобыкс сейчас активно используется в микрофронтенде, а редакс в старом легаси и с него часто мигрируют на пример на react-query
Так. Мы наделали на mobx систему для конструирования умного дома из
Конструктора компонентов PLC
Конструктора структуры проекта автоматизации, включая расстановку периферийных устройств и прокладки кабелей
Транспилятора кода на c++
Редактора кода (Монако)
Эмулятора проекта на Webasm в воркере
И ещё дофига всего.
Mobx идеален для всего. Любых размеров. Архитектура на экшенах в редьюсер - это буквально оверинженеринг всегда. *
Если вы пишете не для микроконтроллеров.
Какой Redux? Какой MobX? Какой 2023э4 год? Оба инструмента не нужны в современном React, и больше вредят проектам, чем несут пользы.
MobX был от части способ реализовать быстрый рендеринг в React, и только поэтому получил хоть какое-то распространение. Сегодня он просто слишком большой и сложный по дизайну, чтобы тащить это чудо в новый проект.
Redux ужасен сам по себе, и просто делает разработку большого проекта - пыткой.
А как принято в современном риакт? Можно с обоснованием и примерами?
Какой Redux? Какой MobX? Какой 2023э4 год? Оба инструмента не нужны в современном React, и больше вредят проектам, чем несут пользы.
Серьезно? Т.е. использовать встроенный в реакт стейт менеджмент это нормально? :D У меня для вас очень плохие новости.
Сегодня он просто слишком большой и сложный по дизайну, чтобы тащить это чудо в новый проект.
MobX - 17kb gzip это много? Ахахах это в эпоху 4G/5G где загрузка 1mb (в 50+ раз больше размера MobX) занимает в среднем 100ms если интернет так себе. Итого цена вопрос 2ms в противовес максимальному удобству и качеству для кода. С вами точно всё в порядке?)
Отсортируем либы по увеличению удобства и функциональности:
Redux + RTK + ReSelect = 15КБ
MobX = 16КБ
$mol_wire = 7 КБ
Вот это магия - самая продвинутая либа оказалась ещё и самой компактной!
А пока вы ставите минусы в попытке убежать от реальности, добавлю, что она ещё и минимум в 3 раза быстрее:
Ох не вам говорить о побеге от реальности... Сколько вы уже со своим $mol-ом носитесь? 6 лет, 7? А воз и ныне там
За эти годы помимо крутейшей реактивной системы, у нас появился шустрейший движок 3d ренеринга, наибыстрейшая система векторной графики, децентрализованная субд с рилтайм синхронизацией, коллаборативный визивиг редактор огромных документов, полная виртуализация рендеринга, обширная документация с кучей примеров, множество других библиотек, компонентов и запущенных проектов. А у вас?
Серьезно? Т.е. использовать встроенный в реакт стейт менеджмент это нормально? :D У меня для вас очень плохие новости.
Весь во внимании, какие такие плохие новости у вас есть для меня.
MobX - 17kb gzip это много
Я не упоминал о размере тех или иных библиотек. Будем честны - это последнее, что забодит, если речь идет о SPA.
противовес максимальному удобству и качеству для кода
Качество кода можно сохранять без использования MobX. MobX - ненужна, переусложненная абстракция, которая не дает ни одного явного преимущества в реальных React-приложениях.
Качество кода можно сохранять без использования MobX. MobX - ненужна, переусложненная абстракция, которая не дает ни одного явного преимущества в реальных React-приложениях.
Да вы что? Т.е. нативное изменение переменных это не явное преимущество? Вы точно как-то связаны с разработкой или так чисто по приколу?
Весь во внимании, какие такие плохие новости у вас есть для меня.
Не знаю как сформулировать так чтобы не обидеть, поэтому лучше не буду) Я думаю вы так всё понятно какой склад ума и какой "код" пишут те, кто выбирает встроенный реактовский стейт менеджмент)
Удачи с дебагом и хендлингом кеша! Ваш код выглядит великолепно, и эффективно!
Удачи с дебагом
Шта?)) Вы не знаете что такое Find References в IDE?) Вы не знаете что такое console.log?) И в конце концов вы что часто дэбажете? Хотя судя по вашим суждениям дэбаг это 50% вашего времени, ибо с таким подходом подругому и не может быть) Я например максимум 1-2 раза в год дэбажу, а время на это уходит обычно 2-3 минуты, 5 минут если прям совсем сложный кейс. Хвала Find References и console.log за возможности молниеносного дэбага.
Мне вот просто интересно даже как можно дэбажить больше 5 минут когда за 2 клика IDE показывает все места где читается и изменяется интересующая вас переменная, потом вы вставляете console.log в тех местах где заподозрили причину бага, потом обновляете страницу, идете по баженому сценарию и вуаля, в консоли лежит ответ.
и хендлингом кеша!
Шта???) Вы о чём вообще?)
Ваш код выглядит великолепно, и эффективно!
Разумеется, ведь он нативный и максимально очевидный и понятный. Просто читаешь его слева-направо сверху-вниз и тебе понятен абсолютно каждый шаг.
Если через 5 лет вы еще останетесь во frontend - разработке, придите, и перечитайте свой комментарий.
и хендлингом кеша!
Шта???) Вы о чём вообще?)
Именно так. Недостаточно просто получить данные, и надеяться, что этого достаточно.
Что будет, если 2 компонента вызовут fetch?
Что будет, если компонент часто монтируется? Каждый раз дергать fetch?
Как выполнять оптимистичное обновления стейта (например при сабмите формы) и отменять его при ошибке запроса?
Как инвалидировать данные, если пользователь долго не меняет стейт приложения (долго держит вкладку открытой)?
Как делать повторную попытку запроса, если произошла ошибка?
Как обрабатывать ошибки? А как обрабатывать ошибки при инвалидации данных?
Как отменять запрос (`AbortController`), если компонент размонтировался, или просто хочется сделать это глобально?
Если ваш механизм получения данных не покрывает хотя бы один из этих пунктов, то ваше приложение не отвечает современным требованиям по работе с данными, и не пройдет ни одну техническую экспертизу.
В тоже самое время, куда больший функционал покрывает Tanstack Query или SWR - оба с безупречной репутацией и многолетней поддержкой.
Мою техническую проверку эти антипаттерны точно бы не прошли:
Что будет, если компонент часто монтируется?
Как выполнять оптимистичное обновления стейта (например при сабмите формы) и отменять его при ошибке запроса?
Как инвалидировать данные, если пользователь долго не меняет стейт приложения (долго держит вкладку открытой)?
И что из указанного вы считаете плохим/ненужным поведением?
Я же процитировал..
Хорошо, перефразирую: разве вам не приходилось решать проблемы, которые вы процитировали?
Это не проблемы, а кривые решения. В этом смысле это, конечно, проблемы, которые решаются выпиливанием.
По-вашему, сделать для пользователя удобное приложение - это кривое решение? Либо за вашей несуразной критикой скрывается нежелание решать реальные бизнес-кейсы, либо полное их непонимание.
В удобном приложении компоненты не ремонтируются. Скорее всего вы взяли кривой инструмент и получили кривой результат, который потом лечили другим кривым инструментом.
В удобном приложении показывается реальное состояние, а не враньё про сделанную работу с откатами состояний, которые уже повлияли на другие состояния. Скорее всего вы не знаете с какими корнер кейсами реально сталкиваются пользователи ваших "оптимистичных" интерфейсов.
В удобном приложении уведомления прилетают в реальном времени, а не долбят сервер тяжёлыми запросами по таймауту. Скорее всего вы не умеете готовить серверные нотификации.
Вы либо намеренно "сужаете рамки", либо, как я сказал, не понимаете критериев.
В удобном приложении компоненты не ремонтируются
Это неправда. Я могу закрыть, а потом снова открыть карточку товара. Если это происходит за короткий промежуток времени, я бы не хотел видеть спиннер каждый раз, когда открываю карточку, которую только что закрыл.
В удобном приложении показывается реальное состояние, а не враньё про сделанную работу с откатами состояний
Это не так. Если вы используете websockets, для лучшей отзывчивости интерфейса вы должны использовать оптимистичные апдейты, иначе вы заставляете пользователя ждать в 99.9% случаев, когда запрос завершается успешно
В удобном приложении уведомления прилетают в реальном времени
Вы говорите о дизайне приложения, где сервер может присылать уведомления на клиент о том, что состояние изменилось. Во-первых, на уведомления сервера никогда нельзя полагаться. Во-вторых, это никак не устраняет проблемы инвалидации кеширования, так как событие с сервера также приходит с задержкой, и на актуальность его данных полагаться нельзя.
Ага, давайте делать вид, что под "часто монтируется" вы имели ввиду бешенного хомячка перед клавиатурой, а не кривую эвристику Реакта по реиспользованию компонент. Запросы прямо из компонент минуя слой модели, кстати, тоже антипаттерн.
В условиях плохой связи ваши офисные 99.9% превращаются в полевые 0.01%. Почитайте лучше про реалистичные апдейты.
Если на ваш сервер нельзя полагаться в одном, то с чего вы решили, что на него можно полагаться хоть в чём-то? Вы думаете по вебсокетам пакеты идут дольше, чем по http?
Веб-сокеты сложны сами по себе, и далеко не каждый backend будет заниматься реализацией их реализацией. Обычно, все что у вас есть - REST API / GraphQL.
В случае же, если вы действительно решили использовать сокеты, то без CRDT - это просто баловство.
Нет в вебсокетах ничего сложного, это один из самых простых бинарных протоколов, требующий всего пару сотню строк на реализацию с нуля.
А вот CRDT действительно позволяет в оптимистичные апдейты, ибо гарантирует слияние.
Основные трудности с WS начинаются тогда, когда у вас несколько серверов, а также сложно управлять балансировкой. Аутентификация - тоже непросто.
С WS, как с обычным POST/GET, не получится побыстрому поднять лямбду, выполнить запрос и выключить ее.
Если вы действительно пошли в WS, ваша команда должна точно понимать, какие цели они преследуют, и достаточна ли квалификация разработчиков.
А если предметно - эта дискуссия не имеет смысла. Вы - энтузиаст, продвигающий собственной решение, что похвально, но делаете это в довольно токсичной форме. А я отвечаю за использование инструментов для приложения, срок поддержки которого минимум 10 лет.
Так что весь разговор будет сводиться примерно к "я конечно все понимаю, но кто ваши мэинтейнеры?"
Да-да, я пороха не нюхал, а вы серьёзный дядя. Если хотите, чтобы вас воспринимали серьёзно, то не говорите глупостей и не обижайтесь на правду.
Я где-то сказал, что вы пороха не нюхали? Я лишь отметил, что наши собственные желания бизнес не интересует.
Если в проекте, куда ты пришел, уже все написано на React, то, пожалуй, приходится мириться с этим, и думать о том, как улучшить хотя бы инкрементально, но не переписывать все на новый модный фреймворк.
А вы покажите бизнесу честные раскладки сколько постоянно приходится тратить лишних денег из-за кривого инструмента, и какая экономия будет с переходом на более технологически продуманный, а не очередной новомодный.
Вообще, забавно слышать про "не переписывать", когда в реакт экосистеме всё переписывают каждые пару лет: то вкручивают редакс, то выкручивают, то на классах пишут, то на функциях и тд.
Так вроде бы тихая революция уже произошла, и победит HTMX. Пока для него недостаточно тулинга, привычного для frontend-разработчиков. Но, кажется, скоро не останется самих frontend-разработчиков, если HTMX получит широкое распространение.
На HTMX уже сегодня переводит свои старые сайты большой бизнес. By design HTMX предполагает серверный рендеринг в обычный plain html. Оказалось, что даже старенький WordPress можно сделать таким, что он не будет уступать React по базовым требованиям к SPA.
Что будет, если 2 компонента вызовут fetch?
зачем в компонентах вызывать fetch? пусть себе компоненты (хоть сотня компонентов) рисуют данные, которые лежат в одном единственном месте.
Что будет, если 2 компонента вызовут fetch?
Какой код напишите, то и будет. Что за вопросы. Код работает ровно так как вы его спроектируете.
Что будет, если компонент часто монтируется? Каждый раз дергать fetch?
Какой код напишите, то и будет.
Как выполнять оптимистичное обновления стейта (например при сабмите формы) и отменять его при ошибке запроса?
Ну берешь такой, код написал и вуаля - работает. Всё решается нативно же, множеством разных способов.
Как инвалидировать данные, если пользователь долго не меняет стейт приложения (долго держит вкладку открытой)?
Ну берешь такой, код написал и вуаля - работает. Всё решается нативно же, множеством разных способов.
Как делать повторную попытку запроса, если произошла ошибка?
Ну берешь такой, код написал и вуаля - работает. Всё решается нативно же, множеством разных способов.
Как обрабатывать ошибки? А как обрабатывать ошибки при инвалидации данных?
Ну берешь такой, код написал и вуаля - работает. Всё решается нативно же, множеством разных способов.
Как отменять запрос (`AbortController`), если компонент размонтировался, или просто хочется сделать это глобально?
Ну опять же, вариантов масса. Ладно, так и быть, тут даже приведу пример, ибо это все так же отнимает 3 минуты, вот прям на коленке сходу:
Если ваш механизм получения данных не покрывает хотя бы один из этих пунктов, то ваше приложение не отвечает современным требованиям по работе с данными, и не пройдет ни одну техническую экспертизу.
Да вы что? Сотни тысяч реализованных проектов по всему миру говорят от обратном.
В тоже самое время, куда больший функционал покрывает Tanstack Query или SWR - оба с безупречной репутацией и многолетней поддержкой.
Серьезно?)) И писать вот такой код прибитый к реакту?)
А вы знаете толк в извращениях. Оно и видно, что у вас реакт головного мозга образовался. Реакт это view слой, больше он ни на что не годен. Его встроенные механизмы управления состоянием максимально убоги и топорны.
Давайте я сразу пропущу и ваши доводы, и ваш ужасный код - все это смехотворно.
Но вот на чем я действительно хотел бы заострить ваше внимание, так это на том, что у вас какая-то боязнь писать код специфичный для того фреймворка, с которым работаете. Вы привели пример совершенно нормального, чистого хука на SWR, и если это вызывает у вас старых, то, пожалуй, мы бы с вами не сработались.
Давайте я сразу пропущу и ваши доводы, и ваш ужасный код - все это смехотворно.
В каком месте он ужасный? Он не понятный? Он не очевидный? Он легко не читается слева-направо сверху-вниз?
у вас какая-то боязнь писать код специфичный для того фреймворка, с которым работаете
У меня нет никаких боязней. Всё просто, если бы у реакта было нормальное управление состоянием, я бы его использовал, но т.к. оно плохое, то я использую MobX. Вот например во Vue3 я бы использовал встроенный во vue инструмент реактивности, т.к. он главное как и mobx построен на getters/setters и автоматической подписке/отписке. Но всё же связка react + mobx мне нравится гораздо больше.
У React - понятное и удобное управление состоянием, без лишней магии. Почему-то подавляющему большинству React-сообщества встроенные хуки нравятся. Вероятно, вы считаете, что это неудобно, и все вокруг ошибаются. Но, что, если ошибаетесь вы и просто плывете против течения впустую?
У React - понятное и удобное управление состоянием, без лишней магии.
Оно убогое и максимально топорное. Управление состоянием не основанное на getters/setters это изначально провальный вариант.
Почему-то подавляющему большинству React-сообщества встроенные хуки нравятся. Вероятно, вы считаете, что это неудобно, и все вокруг ошибаются.
Как вы думаете, подавляющее большинство людей - умные или нет? Так вот, умных людей дай бог 1% от всего населения земли, а реально умных жалки доли процента. Если что я себя не приписываю к каким-то особо умным, просто я не глупый.
Это впрочем ответ на ваше "почему".
Ну и ещё одна вариация ответа более наглядная - миллионы мух не могут ошибаться, не так ли?)
Но, что, если ошибаетесь вы и просто плывете против течения впустую?
Я плыву против течения не потому что я идиот) А по другим причинам) Думаю вы поймете это из блока выше) Альберт Эйнштейн тоже плыл против течения, но по итогу надеюсь вы знаете что он как раз плыл в нужном направлении.
пп. 0-6
МобХ - это просто библиотека реактивности. По сути она просто определяет, как будет выглядеть ваш код. Как перечисленные 7 требований могут быть с этим связаны, и какие могут возникнуть дополнительные трудности с ними, если выбрать реактивность на проксях?
В тоже самое время, куда больший функционал покрывает Tanstack Query или SWR - оба с безупречной репутацией и многолетней поддержкой.
В том же ТанстекКвери, самая крутая фича - продвинутое управление запросами и кэшированием на любой вкус. Теперь это есть отдельным пакетом, который можно прикрутить к любому фреймворку
Понимаю, что здесь уже сложно держать один вектор дискуссии. Изначально, мы говорили о MobX. Затем перешли к получению данных на примере кода комментатора выше.
Вы действительно можете использовать возможности Tanstack в том числе для MobX. Чего я не понимаю совершенно, так это для чего в современном проекте на React нужен MobX.
Redux имеет высокий порог вхождения и сложную кривую обучения
Впервые столкнулся с redux в 2017 году. Сперва действительно показалось очень сложно. Мне потребовалось порядка двух или даже трёх часов, чтобы разобраться с ним. И вот я не понимаю, как можно говорить о каких-то там кривых обучения, если нужно всего лишь прочесть документацию и посмотреть примеры?
Хотелось бы увидеть в "плюсы" и "минусы" перечисленных state management'ов информацию о тестировании
А почему ни слова о@preact/signals
в 2024?
Ну не совсем по-другому. Да проще, но все ещё многословно
Добавил блок с redux-toolkit
Пришлось аж зарегаться, чтобы подушнить)) Код выглядит из примеров как в 2019 а не 2024. connect в Redux серьёзно? Redux toolkit в помощь. UseSelector и UseDispatch туда же.
Кто-то в комментариях написал, что ничего кроме mobx и быть не может.
Советую автору и другим обратить внимание на другие миллион существующих стейт менеджеров а не топтаться на этом старье...
Например Tanstack Query, Zustand, Jotai посмотреть.
Пригодных к продакшену стейтменеджеров не то чтобы много: https://page.hyoo.ru/#!=3ia3ll_rcpl7b
И среди них перечисленных вами нет.
Спасибо за комментарий, обновил статью и добавил блок с Redux Toolkit
Даже не знаю, что сказать.
Если сравнивать Mobx с Redux Core, то однозначно Mobx.
Если же говорить о RTK, то он уступает только с асинхронными операциями, потому что RTK Query такое себе, но в остальном он также просто настраивается и масштабируется.
Использую mobx для маркетплейса.
Статья весьма поверхностно сравнивает mobx и redux.
Декораторы на mobx уже не в моде, сейчас можно обойтись makeAutoObservable. Нет упоминания о mobx-state-tree и redux toolkit.
Не сказано о том, что такое наблюдаемые данные данные в mobx - mobx мемоизирует компоненты с помощью observer, ререндер происходит только если в компоненте происходит обращение к данным которые изменились. Например если в компоненте происходит обращение к объекту, но не к его свойству которое поменялось, ререндер не произойдет, в этом главная сила оптимизации mobx.
Последние лет шесть использую mobx. При этом в паре проектов была долгоиграющая задача - буквально переписать с reduxa на mobx.
По ощущениям, mobx - это реально серебряная пуля для проектов любого уровня сложности. Особенно это ощущается на долгосроке, при кардинальных изменениях требований и сценариев.
Мобх также позволяет вообще забить и забыть про апи реакта, про все его useMemo, useCallbackи, useContextы и не следить за этим впринципе. Реакт - используется просто как шаблонизатор с предельно тупыми компонентами. Вся логика в сторах, в ооп-стиле, на обычном javascript, сверху вниз. Никакой функциональной вакханалии. На одном проекте, которому пару лет уже - до сих пор нет ни одного useState-а!!
И да, никаких проблем с дебагом, или проблем "скрытой магии" нет вприницпе.
И ещё плюс - бекенд разработчикам понятен код))
А когда ещё и Реакт выпилите - совсем себя белым человеком почувствуете.
В Redux заложен квадратичный рост сложности вычислений при росте числа элементов, поэтому он категорически не подходит для больших приложений. Единственная интересная фича - time machine, за которую, однако, приходится платить очень дорого.
Если разработчик в 2024 году продолжает использовать Redux, когда уже весь мир от него отказался - это красный флаг на собеседовании. Рекомендую никому не рассказывать, что вы его используете, и мигрировать на что-то более продуманное) Хоть даже тот же MobX
Тот случай, когда комментарии доставляют больше, чем сама статья, но всё равно спасибо ?
По существу - сравнивать редакс с #any-state-manager# в 2024 - неблагодарное занятие. Как идея для статьи - попробовать сравнить актуальные подходы управления состоянием из коробки (рекомендуемые авторами) в разных фреймворках (react, vue, angular, svelte...)
Если выбирать между этими двумя - я бы выбрал Zustand - практически ничего не весит, не привносит никакой ментальной нагрузки + простой и выразительный синтаксис и огромные возможности
Redux vs Mobx кого же выбрать для React-приложения в 2024 году?