Комментарии 12
К Mobx рекомендую пакет, автоматический оборачивающий компоненты в observer: https://github.com/christianalfoni/mobx-react-observer
Это позволяет писать export function Component и в девтулзах всё видно без необходимости 2 раза писать имя компонента. Не возникают рандомные редкие баги когда думал что observer есть, а его нет.
Он срабатывает только на ваши компоненты (внешние компоненты в node_modules остаются прежними) + можно исключать папки. Прям колоссальное улучшение DX
я фронтенд-разработчик в компании VK
Зря вы вот это уточнение написали ;)
Автору спасибо за интересный контент. Вопрос: а как вы связываете мобх с серверным состоянием? Используете ли какие-нибудь бинды типа mobx-react-query?
Спасибо!
К Mobx рекомендую пакет, автоматический оборачивающий компоненты в observer: https://github.com/christianalfoni/mobx-react-observer
Это позволяет писать export function Component и в девтулзах всё видно без необходимости 2 раза писать имя компонента. Не возникают рандомные редкие баги когда думал что observer есть, а его нет.
Он срабатывает только на ваши компоненты (внешние компоненты в node_modules остаются прежними) + можно исключать папки. Прям колоссальное улучшение DX
Концепт автооборачивания действительно улучшает DX, но конкретно этот пакет тянет babel/core и его 15 зависимостей на мегабайты, что на мой взгляд довольно значительная цена. Более легковесных альтернатив с AST трансформацией не видел, но для многих проектов могут подойти трансформации кода регулярками в бандлере - не так надежно, зато 15 строк вместо гигантского дерева зависимостей.
Спасибо за статью. Пользуюсь mobx часто. Но в статье вы не описали пару проблем с которыми я сталкивался. Было бы здорово об этом написать:
1. В примерах вы присваиваете в функциях сразу значения типа store.calls++, но в консоли возникает предупреждение - что менять свойства надо в только в экшенах. Я не до конца понял почему.
2. В асинхронном примере с запросом fetch тоже самое. После await - нельзя писать код который просто стейт меняет, а нужно обернуть в runInAction, или использовать flow из того же mobx, но с ним проблемы с типизацией на Typescript.
Было бы здорово узнать подробнее о такие подводных камнях.
Да, спасибо за внимательность, допишу об этом моменте в статье!
Этот варнинг убирается через настройку
import { configure } from "mobx"
configure({
enforceActions: "never"
})Реактивность в Mobx работает синхронно - при изменении реактивных данных сразу срабатывают реакции. Значит, если вы меняете последовательно 2 переменных store.counterOne++ и store.counterTwo++ , то реактовые компоненты перерендерятся после каждой операции. И если оба этих параметра читаются в одном компоненте - будет лишний ререндер.
Да, далеко не всегда это значительно влияет на производительность, но является очевидной точкой оптимизации, чтобы снизить количество ререндеров. Mobx дает для батчей runInAction и по дефолту пишет ворнинг в консоль, если эта оптимизация не используется - это скорее просто good practice, и вполне можно без этого писать приложения, отключая enforceActions. Я же предпочитаю всегда явно батчи делать и экономить ререндеры.
На Хабре было много дискуссий по этой теме, например в этой разбираются централизованные механизмы автобатчинга и их недостатки.
На крупном проекте столкнулись с большими утечками памяти в MobX (в самой последней версии). При детальном разборе оказалось, что компоненты, обёрнутые в observer, при анмаунте просто не очищались GC, они оставались в detached elements (вкладка Memory в DevTools позволяет собрать такие элементы и вызвать GC над ними). Перешли на Valtio – идейно похожий стор, проблемы с памятью просто исчезли.
Привет, все зависит от того как писать !
У нас тоже были утечки памяти, но они были связаны с тем, что в некоторые reaction не были прикинуты сигналы на удаление
reaction(
fn1,
fn2,
{
signal: this.abortSignal
}
)В общем утечек памяти в самом observer я с уверенностью могу сказать что нет, потому что у нас вкладка с фронтом (два фронта: главное приложение + iframe приложение внутри) после работы GC занимает память 84-86 МB
Важный момент: мы не используем React хуки вовсе в слое представления для БЛ (кроме юайных хуков вроде useTable), поэтому прокси не отправляются в массив зависимостей в хуках, как и не используются в замыканиях в хуках. Это может быть связано с утечками

MobX или приправа реактивности для JS