(Волшебные) эксперименты в состоянии React с использованием библиотеки Valtio

Ли Робинсон написал отличную статью под названием Прошлое, настоящее и будущее управления состоянием React, в которой он исследует текущее состояние управления состоянием приложения React.

Выдающейся библиотекой управления состоянием React была valtio от Daishi Kato, которая возглавляла несколько библиотек состояний, перечисленных в статье Ли, в том числе:

  • Джотай
  • Зустанд
  • и другие!

Согласно своему твиту, Като резюмирует дерево решений для управления состоянием приложения React следующим образом:

Подпишите меня на «волшебно простые решения».

Если вы читали мой предыдущий пост о YAGNI, то знаете, что я сторонник простых решений; еще лучше, когда они волшебно просты.

Чтобы изучить valtio и то, как он управляет состоянием, я создал простое и продуманное приложение, которое:

  1. Случайно добавляет Company
  2. Случайным образом добавляет Employee и присваивает Employee Company
  3. Звонит в службу поддержки по требованию, чтобы получить сумму компенсации за Employee
  4. Агрегирует общую компенсацию за все Employee для данного Company

Репозиторий GitHub доступен здесь.

Найдите минутку, чтобы посмотреть на это в действии ниже, и обратите особое внимание на сумму в долларах после Company :

В то время как Redux использует концепцию неизменного состояния, valtio использует прокси-состояние.

Если вы использовали Vue, то вы уже знакомы с состоянием прокси. По крайней мере, для меня прокси-состояние кажется более естественным, простым для понимания и гораздо менее подробным на практике.

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

— Дайси Като

Давайте посмотрим, как выглядит состояние приложения с valtio:

Вот и все; это просто. Все, что нам нужно сделать, это обернуть его в proxy перед экспортом.

В модели пользовательского интерфейса для отображения компаний мы можем использовать состояние, вызвав useSnapshot(appState):

В строке 27 вызов appState.companies.push() изменит наше состояние реактивным образом и вызовет визуализацию пользовательского интерфейса.

В строке 34 мы загружаем состояние в компонент с помощью снимка . Важно принять это к сведению, поскольку экземпляры объектов, извлеченные из моментального снимка, не подлежат изменению. В valtio мутации должны происходить непосредственно против состояния (строка 27). Мы углубимся в это немного позже.

Обратите внимание на строку 45. Свойство c.salaries представляет вычисленное значение, которое является суммой всех зарплат сотрудников данной компании.

Давайте посмотрим, как Employee добавляется к Company:

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

В строках 45–50 мы добавляем новый Employee, а затем вставляем этот экземпляр в Company… и все просто работает.

В строке 78 все становится немного интереснее. Нажатие кнопки “GET$$” вызовет сервисный вызов веб-службы для получения компенсации за Employee. Затем это значение присваивается Employee и агрегируется по Company .

Давайте посмотрим на класс Employee:

В строке 35 мы делаем вызов веб-службы, чтобы получить случайное значение для назначения компенсации Employeeas.

Следует отметить, что, поскольку мы извлекли этот экземпляр Employee из useSnapshot в EmployeeGenerator.tsx, его свойство compensation не может быть изменено напрямую с помощью this.compensation = compensation (честно говоря, это было бы магией следующего уровня).

На диаграмме ниже визуализируются строки 37–47 из приведенного выше листинга:

Чтобы обновить компенсацию, нам нужно получить оригинал из состояния и изменить это (в этом примере я использую полное имя, но в реальном мире мы использовали бы идентификатор).

Еще интереснее становится, когда мы смотрим на Company :

Взгляните на salaries . Это вычисленное значение с использованием геттера.

Но когда мы обновляем экземпляр Employee, связанный с этим Company, значение этого геттера автоматически обновляется в компоненте.

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

По сравнению с взглядом Томми Грошонга на React MVC, valtio упрощает создание приложения MVC на React.

Я нахожу интересным взгляд Ли Робинсона на критерии отбора:

По крайней мере, для меня valtio кажется абсолютно, смехотворно простым и поистине волшебным.

Дальнейшее чтение

Пост в блоге Дайши Като о внутренностях valtio.

Риккардо Джорато, статья, в которой valtio сравнивается с mobx, еще одним подходом на основе прокси.