Обновить

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

ЗакрепленныеЗакреплённые комментарии

К Mobx рекомендую пакет, автоматический оборачивающий компоненты в observer:  https://github.com/christianalfoni/mobx-react-observer

Это позволяет писать export function Component и в девтулзах всё видно без необходимости 2 раза писать имя компонента. Не возникают рандомные редкие баги когда думал что observer есть, а его нет.

Он срабатывает только на ваши компоненты (внешние компоненты в node_modules остаются прежними) + можно исключать папки. Прям колоссальное улучшение DX


я фронтенд-разработчик в компании VK

Зря вы вот это уточнение написали ;)

Автору спасибо за интересный контент. Вопрос: а как вы связываете мобх с серверным состоянием? Используете ли какие-нибудь бинды типа mobx-react-query?
Спасибо!

Привет!

В данный момент мы разрабатываем чисто CSR апку, но на гитхабе у меня можно найти пример работы MobX в режиме SSR (GOZON), а также да, как вы упомянули, можно использовать mobx-tanstack-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. Я же предпочитаю всегда явно батчи делать и экономить ререндеры.

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

в одном компоненте - будет лишний ререндер.

Насколько я знаю лишнего рендера не будет, потому что 18+ реакт будет автоматически батчить такие апдейты, но mobx реакции вызовутся два раза да

На крупном проекте столкнулись с большими утечками памяти в MobX (в самой последней версии). При детальном разборе оказалось, что компоненты, обёрнутые в observer, при анмаунте просто не очищались GC, они оставались в detached elements (вкладка Memory в DevTools позволяет собрать такие элементы и вызвать GC над ними). Перешли на Valtio – идейно похожий стор, проблемы с памятью просто исчезли.

Привет, все зависит от того как писать !

У нас тоже были утечки памяти, но они были связаны с тем, что в некоторые reaction не были прикинуты сигналы на удаление

reaction(
    fn1,
    fn2,
    {
      signal: this.abortSignal
    }
)

В общем утечек памяти в самом observer я с уверенностью могу сказать что нет, потому что у нас вкладка с фронтом (два фронта: главное приложение + iframe приложение внутри) после работы GC занимает память 84-86 МB

Важный момент: мы не используем React хуки вовсе в слое представления для БЛ (кроме юайных хуков вроде useTable), поэтому прокси не отправляются в массив зависимостей в хуках, как и не используются в замыканиях в хуках. Это может быть связано с утечками

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации