(Волшебные) эксперименты в состоянии React с использованием библиотеки Valtio
Ли Робинсон написал отличную статью под названием Прошлое, настоящее и будущее управления состоянием React, в которой он исследует текущее состояние управления состоянием приложения React.
Выдающейся библиотекой управления состоянием React была valtio
от Daishi Kato, которая возглавляла несколько библиотек состояний, перечисленных в статье Ли, в том числе:
- Джотай
- Зустанд
- и другие!
Согласно своему твиту, Като резюмирует дерево решений для управления состоянием приложения React следующим образом:
Подпишите меня на «волшебно простые решения».
Если вы читали мой предыдущий пост о YAGNI, то знаете, что я сторонник простых решений; еще лучше, когда они волшебно просты.
Чтобы изучить valtio
и то, как он управляет состоянием, я создал простое и продуманное приложение, которое:
- Случайно добавляет
Company
- Случайным образом добавляет
Employee
и присваиваетEmployee
Company
- Звонит в службу поддержки по требованию, чтобы получить сумму компенсации за
Employee
- Агрегирует общую компенсацию за все
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 мы делаем вызов веб-службы, чтобы получить случайное значение для назначения компенсации Employee
as.
Следует отметить, что, поскольку мы извлекли этот экземпляр 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, еще одним подходом на основе прокси.