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

Mobx: библиотека глобальных сторов (state manager)

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров18K

Что такое Mobx?

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

Mobx простая и понятная в использовании библиотека, использующая в своей реализации Context API и, по сравнению с Redux, требующая минимум шаблонного кода для инициализации стора.

Mobx сторы хорошо масштабируются и для каждого стора можно определить его область видимости, помещая соответствующие компоненты внутрь провайдеров стора.

Зачем использовать глобальные сторы?

Глобальный стор упрощает передачу параметров между компонентами, изменение которых вызывает ререндер активного интерфейса.

Также в сторах удобно хранить общие методы — будь то api‑запросы или парсеры данных — которые используются в разных компонентах, но которые сложно передавать передавать между ними по дереву компонентов.

Наглядно поток передачи параметров между компонентами без и с Mobx показан на слайде:

Из чего состоит Mobx хранилище

Mobx стор состоит из двух частей — самого стора с данными и провайдера этого стора.

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

Стор в сущности функция‑генератор, которая возвращает объект. Свойства и методы этого объекта будут доступны во всех компонентах внутри провайдера, и при изменениях этих свойств будет происходить ререндер виртуального DOM.

Файловую архитектуру лучше разграничить так, что после объявления провайдера и стора, файл провайдера изменяться не будет, но из него мы только будем импортировать компонент провайдера и хук возвращающий сохраненный в контексте стор.

Изменяться и дополняться новыми атрибутами, таким образом, будет только объект стора, находящийся в отдельном файле, но помните, что фактически в компоненты из него напрямую ничего импортироваться не будет.

Начало работы

Для того чтобы начать использовать Mobx в react-приложении его нужно установить:

npm i mobx mobx-react-lite

Затем чтобы объявить стор, создадим в корне проекта папку stores, и в ней папку для нового стора - AppStore. В этой папке создадим два файла - для провайдера и для обьекта-стора соответственно. Также можно добавить в папку index.js, чтобы задать импорт провайдера из папки AppStore по дефолту.

Файловая структура стора, таким образом, будет выглядеть так:

/stores

   /AppStore

     AppStoreProvider.jsx

     AppStore.js

     index.js

Объявление провайдера и стора

Давайте обьявим провайдер и стор, в котором будет глобальная переменная test и метод для ее изменения toggleTest:

AppStoreProvider.jsx

import { createContext, useContext } from 'react';
import { observer, useLocalObservable } from 'mobx-react-lite';
import { createAppStore } from './AppStore';

const Context = createContext(null);

export const AppStoreProvider = observer(({ children, ...props }) => {
  const store = useLocalObservable(() => createAppStore(props));
  return <Context.Provider value={store}>{children}</Context.Provider>;
});

export const useAppStore = () => {
  const store = useContext(Context);
  if (!store) throw new Error('Use App store within provider!');
  return store;
};

AppStore.js

export const createAppStore = (props) => {
  return {
    test: props.test || 'Hello world',
    toggleTest: function () {
      this.test = this.test === 'Hi!' ? 'How are you?' : 'Hi!';
    },
   
  };
};

После создания провайдера и стора нужно обернуть компоненты, использующие стор, в провайдер. Это нужно для доступа к объектам хранилища.

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

import React, {} from 'react';
import {AppStoreProvider} from '~store/AppStore'; // index.jsx
import {MyComponent} from './MyComponent';

export const App = () => {
  return (
    <AppStoreProvider>
      <MyComponent />
    </AppStoreProvider>
  );
}

Также, здесь мы можем передать исходные значения для стора:

Затем мы можем использовать стор в компоненте.

Для того, чтобы компонент ререндерился при изменении стора, его самого нужно обернуть в функцию observer из библиотеки mobx‑react‑lite.

Сохраненный стор получают из кастомного хука useAppStore:

import React from 'react';
import {observer} from 'mobx-react-lite';
import {useAppStore} from '~store/AppStore'; // index.jsx

export const MyComponent = observer(() => {
  const appStore = useAppStore();

  return (
    <>
      <h1>{appStore.test}</h1>
      <button onClick={() => appStore.toggleTest()}>Toggle</button>
    </>
  );
});

Локальное хранилище

Также с помощью Mobx можно создать локальное хранилище для отдельного компонента. Доступ к небу будет только у этого компонента. Это удобно, если логику нескольких useState нужно вынести за область компонента. Также в локальное хранилище можно вынести некоторые методы, чтобы разгрузить тело компонента. Для добавления локального хранилища его нужно инициализировать в компоненте:

const localStore = useLocalStore();

И объявить само хранилище в отдельном файле файле:

import { useLocalObservable } from 'mobx-react-lite';

const createLocalStore = (props) => {
  return {
    hello: props.hello || 'Hello world',
    toggleHello: function () {
      this.hello = this.hello !== 'Hi!' ? 'How are you?' : 'Hi!';
    },
   
  };
};

export const useLocalStore = (props = {}) => {
  return useLocalObservable(() => createLocalStore(props));
};

Подведем итог

На примере видно, как просто обьявить mobx стор и вызывать его в компоненте.

Определенно, преимуществом Mobx по сравнентю с Redux является простота - как в обьявлении так и в поддержании сторов. Цепочка вызова в Mobx простая - обьявляете переменную или метод в сторе и достаете ее из хука в компоненте - не нужно иметь дело ни с какими редисерами и мидлварами.

Так что используйте Mobx и избегайте редукса головного мозга :)

Ссылка на документацию:

https://mobx.js.org/react-integration.html

спасибо

Теги:
Хабы:
Всего голосов 1: ↑1 и ↓0+1
Комментарии22

Публикации

Истории

Работа

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
26 октября
ProIT Network Fest
Санкт-Петербург
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань