Открыть список
Как стать автором
Обновить

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

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

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

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

Что касается конкретно вашего Biscuit-store:
Честно ерунда полнейшая. Очередная redux-like поделка. Вопрос зачем?? Если есть MobX который на порядок лучше абсолютно по всем параметрам всех redux-like поделок и redux'a. Вот вообще по всем.
Мне, если честно очень неприятно отвечать на вашу абсолютно не обоснованную, неконструктивную, агрессию. Но.

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

Тут вы неправы… По воле судьбы я сейчас работаю  на проекте завязанном, на Mobx, в котором принимают участия более 5 смежных команд.
И поверьте то что я написал, я взял не из своей бурной фантазии.

Если есть MobX который на порядок лучше абсолютно по всем параметрам всех redux-like поделок и redux'a.

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

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

Каждый инструмент по-своему хорош.

Конкретно ваш инструмент не имеет ни одного преимущества по сравнению с MobX'ом. Поэтому «Каждый инструмент по-своему хорош.» не этот случай.

Тут вы неправы… По воле судьбы я сейчас работаю на проекте завязанном, на Mobx, в котором принимают участия более 5 смежных команд.
И поверьте то что я написал, я взял не из своей бурной фантазии.

Значит в вашем конкретное случае, компетенция разработчиков на этом проекте оставляет желать лучшего. Тем более, это всё равно не отменяет того что я писал ранее, а именно:

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

Но если вы разрабатываете более крупный проект, над котором работают смежные команды, то от всей этой архитектурной свободы вы скорее всего получите максимум боли
Не понимаю зачем включать в статью голословные заявления и объяснять это субъективным мнением. Мнение без аргументов бесполезно и вредно. Касательно вашего примера — какой смысл разделять стор от экшенов? Зачем прокидывать экшны в аргументы observer? Что за странная конвенция импортировать connect как adapter и добавлять его в массив middleware? У вас стор импортируется из модуля инициализированный, как мне создать 2 инстанса стора (пример — 2 независимых инстанса duck)? Как написать юнит-тест на стор, не сбрасывая его состояние перед каждым тестом? Напоминаю, что импорт из модуля делает стор синглтоном. Почему экшн duckQuack переименовался в setQuack? При чтении кода возникают регулярные WTF, которые не возникают при чтении кода на Mobx:

const createDuck = () => {
  return makeAutoObservable({
    value: '',
    swim() {
      this.value = 'duck swims'
    },
    fly() {
      this.value = 'duck flews'
    },
    quack() {
      this.value = 'duck quacks'
    }
  })
}

const App = observer(() => {
  const [duck] = useState(createDuck);

  return (
    <div className='DuckWrapper'>
      <p>action: {duck.value}</p>
      <button onClick={duck.quack}>Duck quacks</button>
    </div>
  )
})

Постараюсь конструктивно ответить вам.

Не понимаю зачем включать в статью голословные заявления и объяснять это субъективным мнением.

Ваше замечание вполне уместно, в случае с mobx я действительно скупился на текст. Тем не менее в статье я меньше всего хотел сравнивать инструменты, а просто-напросто рассказать что меня побудило на создание своего state-manager.

Какой смысл разделять стор от экшенов?

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

Зачем прокидывать экшны в аргументы observer?

Если вы подробно ознакомитесь с паттерном проектирования observer,  то поймете что явное указание подписчиков в слушателе является более правильной практикой.
  • Явное указание зависимостей делает код более очевидным;
  • Ручная подписка на определенные состояния помогает избежать незапланированных перерисовок компонента.


Что за странная конвенция импортировать connect как adapter и добавлять его в массив middleware?

Тут я честно говоря не знаю что вам ответить… Для меня так удобней. Export/import гибкий  инструмент всегда можно сделать так как удобней вам.

У вас стор импортируется из модуля инициализированный, как мне создать 2 инстанса стора (пример — 2 независимых инстанса duck)? 

А зачем? Что бы ваш код было сложней поддерживать? Biscuit ориентируется на подход с централизованными контейнерами состояний и сам по себе является инстансом объекта store.  Если вы работаете, например localStorage вы же не делайте кучу его инстансов… Тут похожий подход.

Как написать unit-test на store, не сбрасывая его состояние перед каждым тестом?

Я честно говоря не понимаю зачем вам нужен тест конкретно store… Функция  createStore уже протестирована за вас. Тесты  будет уместней писать для конкретных  actions. Сейчас это можно организовать на моках. В ближайшем будущем планирую написать инструмент для тестирования. 
P.s. Mobx действительно удобно тестировать, как и любой класс, этого я ни в коем случае не отрицаю.

Почему экшн duckQuack переименовался в setQuack?

Это вопрос реализации, а не подхода.

В вашем примере для меня непонятна реализация с useState. Зачем имплементировать встроенный state-managment React совместно со  стейт-машиной mobx? А Так же. Возможно я ошибаюсь, но ваш store  предоставляет мутабельное поле value во внешний мир, Нарушая принцип инкапсуляции. 
Лично для меня observer mobx неочевиден по вышеуказанным причинам.
чем больше есть возможностей декомпозиции тем лучше.
Код более поддерживаемый когда он имеет не только низкую связанность (coupling), но и высокую связность (cohesion): medium.com/clarityhub/low-coupling-high-cohesion-3610e35ac4a6
Это значит, что код, который меняется вместе, должен быть рядом. Следствием этого и появились компонентные фреймворки, позволяющие писать HTML / JS / CSS рядом — в одном или нескольких файлах, у которых высокий cohesion. И разделение ответственности это не о том, чтобы разделять ради разделения, а о том, чтобы при изменени одного модуля не нужно было править другие, несвязанные с этим модули: www.didoo.net/wp-content/uploads/2017/02/separation-of-concerns-800x522.png
В контексте стейт-менеджеров я плохо представляю ситуацию когда стейт существует без экшнов или экшны существуют без стейта. Или когда вычисляемые значения зачем-то держат отдельно от стейта (без которого они никогда не используются). Поэтому подход Mobx более удачный — computed / action / state в одном файле.
Если вы подробно ознакомитесь с паттерном проектирования observer, то поймете что явное указание подписчиков в слушателе является более правильной практикой.
Там пример для бекенда и там ни слова о том, что это более правильная практика — на бекенде по-другому нельзя. На фронте можно вычислять зависимости изменяемых значений через прокси. Именно благодаря им Mobx и запоминает какие компоненты от каких изменяемых значений зависят. Подход называется Transparent Reactive Programming: github.com/mobxjs/mobx/wiki/Mobx-vs-Reactive-Stream-Libraries-(RxJS,-Bacon,-etc)/
Ручная подписка на определенные состояния помогает избежать незапланированных перерисовок компонента.
Ручная подписка как раз может привести к незапланированным перерисовкам компонента, например вы удалили стор из компонента, но забыли удалить его из списка зависимостей у функции observer. У Transparent Reactive Programming этой проблемы нет.
А зачем? Что бы ваш код было сложней поддерживать?
Нет, 2 и более инстанса стора — вполне частая ситуация. Простой пример — сделайте 2 счётчика на странице, независимых, но с одинаковой логикой и без копипаста кода. В Mobx это 2 разных инстанса одного и того же класса.
Зачем имплементировать встроенный state-managment React совместно со стейт-машиной mobx
useState здесь это простой способ сохранения значения между перерисовками. Лишь один из способов использовать Mobx. Встроенный хук useLocalObservable делает тоже самое: github.com/mobxjs/mobx/blob/main/packages/mobx-react-lite/src/useLocalObservable.ts#L8
Стор можно добавить в контекст реакта, тогда он будет глобальным и useState не нужен. Это к Mobx не относится, это лишь способ использовать его в одном из UI-фреймворков.
но ваш store предоставляет мутабельное поле value во внешний мир, Нарушая принцип инкапсуляции.
Это поле никто извне поменять не сможет — Mobx в строгом режиме (по умолчанию в версии 6) запретит изменять его вне экшнов. Ещё никто не мешает создать класс с приватным свойством. Для простого примера это было лишнее.
Если вы не против я ни буду писать вам в ответ еще портянку текста.) Как будет достаточно кармы поставлю вам + за конструктивное и хорошо обоснованное мнение. Я приму к сведению ваши замечания.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.