Налаштування архітектури MobX для React Native-застосунку
Ви створюєте мобільний застосунок на React Native та розумієте, що стейт-менеджмент через Redux забирає до 40% часу на написання boilerplate-коду. За 5+ років роботи з React Native та 50+ реалізованих проєктів ми з'ясували: MobX — найшвидший спосіб впровадити реактивне керування станом. Екшени, ред'юсери, селектори, нормалізація — усе це можна замінити лаконічним спостережуваним сховищем. MobX — реактивний State Manager, заснований на observable-значеннях. Замість диспатчингу — прямі мутації, замість mapStateToProps — observer-обгортка. Для React Native з mobx-react-lite ми отримуємо компактний код без зайвих обгорток. Зв'яжіться з нами для оцінки вашого проєкту.
Наша команда налаштовує MobX-архітектуру під ключ, гарантуючи сумісність з TypeScript, навігацією та push-сповіщеннями. Оцінимо ваш проєкт і запропонуємо терміни від 2 днів. Отримайте консультацію — ми розповімо, як скоротити код на 60%.
Проблеми, які вирішуємо
-
Надлишковий boilerplate: Redux вимагає actionTypes, action creators, reducers, combineReducers — для кожного модуля. MobX з
makeAutoObservableавтоматично позначає поля та методи за вас. -
Асинхронні оновлення: Після
awaitвтрачається контекст дії. ВикористовуємоrunInActionдля безпечних мутацій — це запобігає випадковим змінам поза дією. -
Складність інтеграції: З React Native часто виникає проблема з
useEffectі множинними підписками. MobX зobserver()автоматично відстежує лише використовувані observable, мінімізуючи перемальовування.
Чому MobX кращий за Redux для React Native?
import { makeAutoObservable, runInAction } from 'mobx'; class ProfileStore { profile: UserProfile | null = null; isLoading = false; error: string | null = null; constructor(private userRepository: UserRepository) { makeAutoObservable(this); } async loadProfile(userId: string) { this.isLoading = true; this.error = null; try { const profile = await this.userRepository.getProfile(userId); runInAction(() => { this.profile = profile; this.isLoading = false; }); } catch (e) { runInAction(() => { this.error = (e as Error).message; this.isLoading = false; }); } } get displayName() { return this.profile ? `${this.profile.firstName} ${this.profile.lastName}` : ''; } } makeAutoObservable автоматично позначає поля як observable, методи як action, гетери як computed. У strict mode MobX вимагає action, тому runInAction обов'язковий для асинхронних сценаріїв — це запобігає випадковим мутаціям поза дією.
У компоненті:
const ProfileScreen = observer(({ userId }: { userId: string }) => { const { profileStore } = useStores(); useEffect(() => { profileStore.loadProfile(userId); }, [userId]); if (profileStore.isLoading) return <ActivityIndicator />; if (profileStore.error) return <ErrorView message={profileStore.error} />; return <ProfileView name={profileStore.displayName} />; }); observer() з mobx-react-lite робить компонент реактивним: перемальовка лише при зміні використаних observable-властивостей.
Порівняння продуктивності: MobX vs Redux
| Параметр | MobX | Redux |
|---|---|---|
| Рядків коду на store | 30 | 70 |
| Час на реалізацію | 2-3 дні | 4-6 днів |
| Кількість файлів | 1 | 4+ |
| Перемальовка при зміні | 1 компонент | Залежить від connect |
Як уникнути зайвих перемальовок з MobX?
React Context при зміні даних викликає перерендер усіх споживачів, а MobX точково оновлює лише залежні компоненти. У таблиці нижче — порівняння метрик для типового профільного екрану:
| Параметр | MobX | React Context |
|---|---|---|
| Код для створення сховища | 20 рядків | 35 рядків (Reducer + Provider) |
| Перемальовка на зміну профілю | 1 компонент | Усі підписники Context |
| Час на реалізацію | 2–3 дні | 3–5 днів |
Детальніше про контекст
Для DI використовуємо Provider, але передаємо не дані, а готовий store — це дозволяє уникнути зайвих rerender-ів.Контекст для DI
Передаємо stores через React Context без Provider-ада:
const StoreContext = createContext<RootStore | null>(null); export const useStores = () => useContext(StoreContext)!; // В App.tsx const rootStore = new RootStore(); <StoreContext.Provider value={rootStore}> <AppNavigator /> </StoreContext.Provider> RootStore створює всі store-и та передає залежності між ними.
Головний аргумент за MobX
Порівняно з Redux — у два-три рази менше коду для тієї ж функціональності. Немає actionTypes, mapStateToProps, нормалізації store. Для команд, які цінують швидкість розробки над строгістю — MobX виграє. Офіційна документація MobX рекомендує використовувати makeAutoObservable для спрощення налаштування.
Аргумент проти: менша передбачуваність. Мутації відбуваються напряму, без явного логу диспатчів. Для налагодження підключаємо mobx-react-devtools або mobx-logger.
Що входить у роботу
- Налаштування
RootStoreз інжекцією залежностей. -
StoreContext+useStoresхук. - Базовий Store-шаблон з
makeAutoObservable. - Інтеграція
mobx+mobx-react-liteз бабелом (за потреби). - Unit-тести store-логіки через Jest (чисті тести без React).
- Документація з архітектури та доступів.
- Відео-туторіал для команди.
- Підтримка після деплою (2 тижні).
Процес роботи
- Аналіз вимог і поточної архітектури (1 день).
- Проектування структури Store та зв'язків (0.5 дня).
- Реалізація шаблону та базового Store (0.5 дня).
- Інтеграція з модулями застосунку (аутентифікація, профіль, покупки) — 1 день.
- Тестування та налагодження (0.5 дня).
- Передача та навчання команди (0.5 дня).
Терміни орієнтовно
Налаштування MobX-архітектури з нуля — від 2 до 4 днів залежно від складності застосунку. Вартість розраховується індивідуально — зв'яжіться з нами для оцінки проєкту.
Типові помилки при впровадженні
- Забувають обгорнути асинхронні мутації в
runInAction— отримують warning у strict mode. - Використовують один великий Store замість кількох маленьких — втрачають продуктивність.
- Не використовують
computedдля похідних даних — перерахунок на льоту сповільнює рендер.
Якщо ви зіткнулися з однією з цих проблем — замовте налаштування MobX під ключ. Ми налаштовували MobX у проєктах з 50+ екранами та гарантуємо сумісність з TypeScript, навігацією та push-сповіщеннями.







