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

Ли Робинсон написал отличную статью под названием Прошлое, настоящее и будущее управления состоянием React, в которой он исследует текущее состояние управления состоянием приложения React.
Выдающейся библиотекой управления состоянием React была valtio от Daishi Kato, которая возглавляла несколько библиотек состояний, перечисленных в статье Ли, в том числе:
- Джотай
- Зустанд
- и другие!
Согласно своему твиту, Като резюмирует дерево решений для управления состоянием приложения React следующим образом:

Подпишите меня на «волшебно простые решения».
Если вы читали мой предыдущий пост о YAGNI, то знаете, что я сторонник простых решений; еще лучше, когда они волшебно просты.
Чтобы изучить valtio и то, как он управляет состоянием, я создал простое и продуманное приложение, которое:
- Случайно добавляет
Company - Случайным образом добавляет
Employeeи присваиваетEmployeeCompany - Звонит в службу поддержки по требованию, чтобы получить сумму компенсации за
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 мы делаем вызов веб-службы, чтобы получить случайное значение для назначения компенсации 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, еще одним подходом на основе прокси.