Использование Mobx в качестве менеджера состояний в нативных приложениях React

Опубликовано: 2022-03-10
Краткое резюме ↬ MobX — один из многих инструментов управления состоянием, доступных разработчикам React. В этом руководстве Fortune Kay объясняет, что такое MobX и как вы можете использовать его в своих приложениях React, создав его с нуля.

Управление состоянием является неотъемлемой частью разработки приложений JavaScript, особенно приложений React и React Native. В этом уроке мы узнаем, как использовать библиотеку MobX для управления состоянием; понять основные концепции, некоторые варианты использования и создать простой пример.

Примечание. Базовые знания Javascript и React Native будут очень полезны при работе с этим руководством.

Использование MobX в приложениях React

Состояние — это данные, с которыми работает ваш компонент (компоненты) — оно содержит данные, которые требуются компоненту, и определяет, что компонент отображает. Управление состоянием — это процесс управления тем, как состояние обновляется и передается от одного компонента к другому. Мониторинг и работа с данными в приложении могут быть затруднены, и это необходимо для библиотек управления состоянием. Обработка всех данных для вашего приложения может быть немного сложной, особенно когда ваше приложение увеличивается в размере и усложняется, создание собственного инструмента управления состоянием не только требует много времени, но и сложно. Вот почему вы можете использовать библиотеку управления состоянием.

Однако важно знать, что состояние — это не единственные данные, которые отображает компонент. Компоненты также могут отображать переданные ему свойства.

Опции для управления состоянием

Библиотеки управления состоянием для приложений React Native включают в себя; React Context API, Redux, MobX и Unstated Next.

Хотя каждый из этих менеджеров состояний имеет свои преимущества и недостатки, я лично рекомендую MobX из-за его простоты, минимального шаблонного кода — он не требует изменения вашего кода, потому что по своей сути MobX является и выглядит как JavaScript; вам не нужно менять архитектуру для ее поддержки (в отличие от Redux и, в меньшей степени, Context).

На самом деле это такая невидимая абстракция, что во многих случаях, если вы уберете весь код MobX — декораторы @observable , @computed , @action и наблюдателя , ваш код будет работать точно так же (хотя у него будут некоторые проблемы с производительностью). ) и не ограничивается глобальным состоянием. Вот несколько причин, по которым следует использовать MobX в качестве диспетчера состояний для ваших приложений React Native.

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

Что такое МобХ?

Согласно официальной документации, MobX — это проверенная в боевых условиях библиотека, которая делает управление состоянием простым и масштабируемым за счет прозрачного применения функционального реактивного программирования. MobX рассматривает ваше приложение как электронную таблицу. Логика заключается в том, что все, что может быть получено из состояния приложения, должно выполняться автоматически .

Государственная архитектура MobX
Государственная архитектура MobX. (Большой превью)
Еще после прыжка! Продолжить чтение ниже ↓

Основные принципы и концепция MobX

MobX отличается от других менеджеров состояний следующими концепциями.

1. Состояние

Состояние — это данные, которые содержит ваше приложение — примерно все содержимое его памяти. Это также относится к вашим компонентам.

2. Выводы

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

  • Пользовательский интерфейс,
  • Бэкэнд-надстройки, такие как изменения на сервере.

MobX имеет два основных типа производных:

  • Вычисленные значения
    Вычисляемые значения — это в основном значения, которые могут быть получены из текущего состояния с использованием чистых функций.
  • Реакции
    Реакции в производных — это побочные эффекты, возникающие в результате изменений в состоянии вашего приложения. Они похожи на вычисляемое значение, но вместо создания нового значения реакция производит побочный эффект для таких вещей, как вывод на консоль, выполнение сетевых запросов, постепенное обновление дерева компонентов React для исправления DOM и т. д.

Золотое правило при использовании MobX заключается в том, что при создании значения на основе текущего состояния используйте вычисленное значение.

3. Действия

В отличие от производных, действия — это код, который вызывает изменения в состоянии приложения — код, который изменяет состояние. Это все, что изменяет состояние. С MobX вы можете сделать это явным в своем коде. Действия — это в основном пользовательские события, такие как ввод, отправка данных на сервер или даже запланированные события.

Чтобы лучше понять Actions, давайте рассмотрим пример из документации MobX.

 class Ticker { @observable tick = 0 @action increment() { this.tick++ // 'this' will always be correct } } const ticker = new Ticker() setInterval(ticker.increment, 1000)

Здесь мы устанавливаем тик @observable с начальным значением 0. Затем мы создали приращение функции, которое также является действием, которое обновляет начальное значение после выполнения тика каждую секунду.

Наблюдаемые в MobX

Наблюдаемые или наблюдаемые значения в MobX в основном представляют собой примитивы JavaScript, простые объекты, классы, массивы и карты. В основном они используются, сначала объявляя наблюдаемое и добавляя к нему значение, а затем вызывая его, добавляя @observable, как показано ниже:

 observable(value) @observable classProperty = value

Подход к архитектуре магазина в MobX

Основная архитектура MobX включает в себя такие части и идеи, как сервисы, хранилища, модели представлений и контейнеры, некоторые из которых описаны ниже.

  • Оказание услуг
    Обычно это функция, вызываемая из контейнера; их можно использовать для получения данных из API и добавления в магазин.
  • Магазин
    Как следует из названия, это центральное место состояния, используемое приложением. Обычно в MobX к ним относятся наблюдаемые, переменные, действия и вычисляемые свойства.
  • Контейнер
    Это вызывает service и помещает данные из модели представления в компонент представления в качестве реквизита React (должен быть помечен декоратором @observer ).

MobX в React и нативных приложениях

В учебных целях в этом руководстве мы собираемся создать простое приложение списка, которое позволит пользователю добавлять, просматривать и удалять элементы списка. Мы будем использовать MobX в качестве менеджера состояния в этом приложении, чтобы добавлять списки, обновлять и удалять их из состояния приложения. Однако важно отметить, что вы уже понимаете основные концепции JavaScript и React.

Без лишних слов, давайте начнем!

Настройка вашей среды

Теперь, когда мы знаем, что такое MobX и как он работает, позвольте мне провести вас через настройку вашего проекта.

Во-первых, давайте создадим проект со следующим, напишите следующий код на вашем терминале для инициализации проекта:

 npx create-react-app listapp

Приведенный выше код создаст простое приложение React с помощью пакета create-react-app. Перейдите в каталог проекта:

 cd listapp

Для этого приложения нам понадобятся три компонента:

  • TitleInput
    Он будет содержать название нашего проекта и форму ввода для добавления списков.
  • List
    Это будет форма ввода, которая позволит пользователю добавить список. У него будет кнопка добавления, чтобы добавить элементы нашего списка.
  • ListsDisplay
    Этот компонент будет отображать все элементы пользовательского списка, а также кнопку удаления, которая автоматически создается, когда пользователь добавляет элемент списка.

Мы будем использовать Store.js, чтобы содержать состояние приложения и методы его изменения, аналогичные Redux. Давайте наметим, для чего они будут использоваться.

  • mobx
    Это менеджер состояний, который мы будем использовать для этого проекта.
  • mobx-react
    Это официальные привязки React для MobX.
  • bootstrap
    Мы будем использовать bootstrap версии 4.5 для стилизации нашего проекта.
  • uuid
    Это используется для автоматического создания ключей для удаления списков.

Сделав это, давайте продолжим и установим эти пакеты. Я буду устанавливать их с альтернативой npm, сделанной в пряже:

 yarn add mobx mobx-react [email protected] uuid

После установки пакетов мы запустим наше приложение в режиме разработки, запустив в терминале приведенный ниже код:

 yarn start

Настройка нашего магазина приложений

Давайте создадим магазин для нашего проекта. Во-первых, создайте файл в корневом каталоге нашего проекта с именем ListStore , это будет центральное расположение нашего состояния приложения.

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

 /*** src/Store.js ***/ import { observable, action, computed } from "mobx"; import { v4 } from "uuid"; export class List { @observable value @observable done constructor (value) { this.id = v4() this.value = value } } export class ListStore { @observable lists = [] @observable filter = "" @action addList = (value) => { this.lists.push(new List(value)) } @action deleteList = (list) => { this.lists = this.lists.filter(t => t !== list) } @computed get filteredLists () { const matchCase = new RegExp(this.filter, "i") return this.lists.filter(list=> !this.filter || matchCase.test(list.value)) } }

В приведенном выше коде мы импортировали три функции из mobx .

  • observable
    Он содержит переменную, которую можно обновить в случае изменения состояния.
  • action
    Используется для изменения состояния приложения.
  • computed
    Значения, которые могут быть получены из существующего состояния или других вычисленных значений, они изменяются после изменения состояния.

List класса имеет два значения объекта, которые done , и value , которое будет содержать начальное состояние приложения и модификацию в случае изменений.

Мы хотим, чтобы наш новый список автоматически создавал ключ, чтобы мы могли автоматически получить кнопку удаления после создания списка. Здесь uuid используется для автоматического создания ключей в нашем приложении.

Затем мы добавили функцию addList , которая будет добавлять списки при щелчке с помощью .push() , чтобы поместить список в массив, который мы уже создали в @observable lists .

Функция deleteList принимает List как свойство, которое должно быть элементом, который пользователь хочет удалить. Затем мы устанавливаем значение this.Lists в новый массив после того, как мы удалили выбранный элемент.

И addLists , и deleteList являются действиями, потому что они изменяют состояние нашего приложения при внесении изменений.

Инициализация магазина MobX

Следующим в нашем списке является импорт нашего магазина в наш App.js и использование его в нашем проекте.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Здесь мы импортировали компоненты TitleInput и ListDisplay . Затем мы инициализировали хранилище в нашем App.js , чтобы иметь возможность передавать его в качестве реквизита компонентам TitleInput и ListDisplay .

Обычно это выдает ошибку, потому что мы не работали над другими компонентами, так что давайте сделаем это. Давайте создадим компонент ListDisplay .

ListDisplay

Этот компонент отображает все наши добавленные списки, а также автоматически генерирует кнопку удаления после добавления нового списка.

 import React from 'react' import List from "./List"; import { observer } from 'mobx-react'; function ListDisplay(props) { const { deleteList, filteredLists } = props.store return ( <div> <div className="container"> {filteredLists.map(list => ( <List key={list.id} list={list} deleteList={deleteList} /> ))} </div> </div> ) } export default observer(ListDisplay)

Для этого компонента мы создали функцию ListDisplay и сделали ее обозревателем, также мы деструктурируем функции list и deletelist из хранилища, сделав это, мы упростили передачу потом как объектные пропсы.

Затем мы сопоставляем через filteredLists , чтобы вернуть списки, которые затем используем при построении отдельного списка, передавая возвращенный элемент в качестве реквизита компоненту List .

После этого наш компонент должен выглядеть так с добавленными списками:

Компонент отображения списка
Списки, отображаемые компонентом `ListDisplay`. (Большой превью)

Далее нужно добавить компоненты List и TitleInput .

Компонент списка

Как и другие наши компоненты, наш компонент List будет экспортировать список в качестве наблюдателя, чтобы помочь магазину следить за изменениями.

 import React from 'react' import { observer } from 'mobx-react' function List(props) { return ( <div className="card"> <div className="card-body"> <div className="d-flex justify-content-between align-items-center"> <p className={`title ${props.list.done ? "text-secondary" : ""}`}> {props.list.value} </p> <div> <button onClick={props.deleteList.bind(this, props.list)} className="btn btn-danger font-weight-bold py-2 px-5 ml-2"> Delete </button> </div> </div> </div> </div> ) } export default observer(List)

Я использовал начальную загрузку для создания карточек в первом наборе divs , а также выровнял значок удаления, чтобы переместиться в правую часть приложения. Во-первых, мы создали компонент карты для обработки нашего list , а затем мы создали тег кнопки для button удаления, который будет принимать два объекта этого и передавать реквизит списку, это будет при щелчке, удалит выбранный элемент списка из списки на странице.

Компонент списка
Один компонент списка с кнопкой удаления. (Большой превью)

Далее идет наш TitleInput , который будет содержать нашу форму ввода для добавления списков и название для проекта.

TitleInput

Как и в других наших проектах, мы добавим функцию @observer , чтобы компонент мог принимать свойства из магазина приложений.

 import React, { useState } from 'react' import { observer } from 'mobx-react' function Navbar(props) { const [value, setValue] = useState("") const {addList} = props.store const prepareAddList = (e) => { e.preventDefault() addList(value) setValue("") } return ( <div className="container mt-3"> <h1 className="title">List App</h1> <form onSubmit={prepareAddList} className="form-group"> <div className="row ml-lg-2"> <input className="form-control-lg col-12 col-lg-9 col-sm-12 mr-3 border border-secondary" value={value} type="text" onChange={(e) => setValue(e.target.value)} placeholder="Enter list" /> <button className="col-lg-2 col-5 col-sm-5 mt-2 mt-lg-0 mt-sm-2 btn btn-lg btn-success font-weight-bold"> Add to List </button> </div> </form> </div> ) } export default observer(Navbar)

Во-первых, мы инициализируем начальное состояние. Используя React Hooks, мы добавили начальное состояние с именем values , которое мы установили в пустую строку. Мы используем это для хранения значения того, что вводится в поле ввода. Чтобы узнать больше о React Hooks, вы можете прочитать эту статью Дэвида Абиодуна.

Затем мы вызвали объект для добавления списков в магазин addList и передали его в качестве реквизита из магазина приложений.

Затем мы создали функцию preparedAddList для приема объекта события для форм ввода, а также добавили кнопку для добавления списков вручную по клику.

Почти готово, нам нужно перезапустить сервер нашего проекта, запустив:

 yarn start

И наш TitleInput должен выглядеть так:

Ввод заголовка
Заголовок и компонент ввода. (Большой превью)

Теперь мы закончили со всеми компонентами нашего приложения, так что давайте соберем их в наш App.js Для этого нам нужно импортировать наши компоненты titleInput и ListDisplay . Нам также нужно импортировать наш магазин из компонента Store.

Чтобы MobX работал в нашем приложении, нам нужно передать магазин MobX в качестве реквизита в наше приложение и отдельные компоненты, чтобы они получили свойства и функции в магазине.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

После завершения наше приложение должно выглядеть так:

Приложение с заполненным списком
(Большой превью)

Заключение

MobX — отличный менеджер состояний, особенно для приложений на основе React. Создавая наше приложение списка, мы изучили основные концепции MobX, состояния, производных и действий. Рабочую версию этого приложения можно найти здесь:

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

Ресурсы и ссылки

  • «React Native с MobX — Начало работы», Надер Дабит, Medium
  • «Концепции и принципы» MobX (официальная документация)
  • «Лучшие практики работы с React Hooks», Аденей Дэвид Абиодун, Smashing Magazine