В этом посте вы узнаете, как использовать набор инструментов асинхронного состояния для управления состоянием с помощью реакции с помощью обработчика состояния useAsyncState.
Этот пост является частью следующей серии постов в блоге:
- async-states: библиотека управления состоянием
- асинхронные состояния: использование реакции
- асинхронные состояния: исходный объект
- асинхронные состояния: производитель
- асинхронные состояния: расширенные концепции
- асинхронные состояния: vs. response-query vs redux vs recoil
- реагировать-асинхронные-состояния: SSR
План
- Введение
- Использование реакции и основной библиотеки
- использование асинкстате
- Использование источника
- использованиеПродюсер
Введение
async-states
изначально был написан как доказательство концепции в мире реакции. Самой первой идеей был API, представленный в предыдущем посте, который в основном отвечает всем нашим потребностям. Затем он стал достаточно зрелым, чтобы стать отдельным пакетом, работающим во всех средах с низкоуровневым набором инструментов для управления состоянием (внутренние перезаписи более 7 раз, без влияния на внешний API).
При создании пользовательских интерфейсов наиболее распространенными вариантами использования являются подписка на состояние, чтение его данных и, возможно, манипулирование им из разных мест. Библиотека удовлетворяет эти основные потребности с помощью единственного хука под названием useAsyncState
, который принимает два аргумента:
useAsyncState
использует ту же сигнатуру, что и большинство хуков реакции, поэтому использование немного похоже. Важное отличие состоит в том, что deps
для библиотеки по умолчанию равно empty Array ([])
, а не undefined
. Он используется для обновления вашей конфигурации на основе зависимостей, например модели реакции.
Параметр create
может быть:
string
, который идентифицирует состояние по ключу- Функция
producer
- Объект
source
изcreateSource
,Sources.for
илиuseAsyncState
configuration
объект, который объединяет всю конфигурацию производителя и добавляет специальные для использования реакции.
Это позволяет библиотеке создавать ваше состояние с полным контролем над любым компонентом или любым контекстом выполнения с контекстной полезной нагрузкой и аргументами!
Никаких ограничений и хитростей!
используя реакцию и основную библиотеку
Если вы помните из предыдущего поста, было использование реакции непосредственно с базовой библиотекой, которая не зависит от реакции, вы можете делать такие вещи:
Чтобы поднять планку еще выше, вот производитель, который обновляет состояние в интервале:
Тестируйте здесь! Я даже написал шлюз веб-сокета, используя этот шаблон! (Инструменты разработки также используют что-то подобное).
Вы также подписываетесь на ванильный javascript или любое другое приложение в окне. Мы также можем создать производителей, которые отправляют сообщения другим окнам/воркерам и ждут их ответов. Эти примеры будут повторно рассмотрены в блоге производителя.
использование асинкстате
Возвращаясь к этому волшебному крючку, он позволяет вам
- Создайте
states
доступное в любом месте, которое производит значения черезsuper-powered
производителей. - Подпишитесь на них, если они были созданы ранее.
- Подожди их, если хочешь
- Полный полный контроль над состоянием
Вот наиболее распространенные примеры:
На основе маршрутизации
Обычный способ выполнения поиска и обмена ссылками — это добавление контекстных вещей к вашему URL-адресу, а затем реакция на их изменения через ваш любимый маршрутизатор. Вот как вы можете этого добиться:
Если вы используете загрузчики и действия react-router
, вы можете просто сделать что-то вроде этого:
Оптимистичный интерфейс
Возможность выполнять оптимистичный пользовательский интерфейс была одной из самых первых целей библиотеки.
Производитель питается от ваших args
и payload
, которые он получает через свой параметр props
. На самом деле копия этого объекта props
, содержащего args
и payload
, каждый раз присваивается вашему состоянию.
Если ваше состояние success
, у вас есть реквизиты, которые привели к этому успешному состоянию (а также для статусов error
и aborted
).
Если мы вернемся к нашему примеру с пользовательским поиском, мы можем сделать что-то вроде этого:
Объект state.props
содержит payload
и args
, поэтому в зависимости от того, как определен ваш производитель (использовать любой из них), вы сможете узнать, что было передано и что привело к этому состоянию. Последовательно!
Поиск по мере ввода
Наверняка вы уже видели это уже много раз! Вот почему я оставляю этот раздел для вас, вы можете это сделать!
Общие состояния
Все состояния являются общими и могут быть подписаны из любого места с помощью строкового ключа или исходного объекта.
Взгляните на этот пример здесь:
useAsyncState
может получить только ключ state
(строка) в качестве параметра и сделать все остальное за вас! Протестируйте предыдущий пример здесь.
События
Возможность прослушивать события и реагировать на них — одна из наиболее часто используемых функций в приложениях. Библиотека позволяет это из нескольких мест:
- Из исходного объекта: вы можете использовать метод
on
для регистрации событий, поддерживаемые до сих пор:change (state change)
,cache-change (cache change)
,dispose(state is reset)
. Когда вы вызываетеon
, он возвращает свою очистку, которая удалит это событие. Можно добавить несколько событий, например:pre-change (with preventDefault and stopPropagation ;) )
,pre-run (same)
… и так далее. - Из объекта конфигурации
useAsyncState
: свойство конфигурацииevents
позволяет настраивать события типов:change
иsubscribe (when your component actually subscribes to the state instance)
.change
можно использовать в качестве обратных вызовов при изменении состояния, аsubscribe
можно использовать для атаки наhost
определенные события; какonFocus, onBlur
… и так далее. - Из
useAsyncState().onChange
илиuseAsyncState().onSubscribe
добавляются дополнительные события, например, из свойства конфигурации.
Давайте рассмотрим несколько примеров:
Попробуйте сами здесь! (просто найдите идентификатор больше 10 или буквенно-цифровой, чтобы имитировать ошибку)
Это немного эквивалентно этому:
Разница в том, что вы можете контролировать, когда вызывать onChange
, и это не будет зависеть от рендера (но вы должны разумно поставить deps
вместо useAsyncState
, если вы решите это сделать! Используйте на свой страх и риск!)
Примечание. Использование подобных событий может быть довольно неудобным, если у вас есть несколько экземпляров, объявляющих это событие и подключенных к одному и тому же состоянию: все они будут выполнены. Для решения этой проблемы существует функция runc
!
Теперь давайте посмотрим на subscribe.
Скажем, для предыдущего примера, когда вы выходите и возвращаетесь на вкладку через одну секунду, мы обновляем последние извлеченные данные. Ну, меня действительно раздражает эта функция, присутствующая на каждом веб-сайте социальной сети. дней!). Это может быть так просто:
Игра с ним сюда! Обратите внимание, что onSubscribe
и events.subscribe
совпадают с onChange
и events.change
.
Без использования реакции вы можете вернуться к низкоуровневому исходному API: source.on
. Он используется следующим образом:
Кэш
Вы уже должны знать о кеше из предыдущих примеров. Внутренний тип за ним:
Итак, в основном вы контролируете:
enabled
: Включить кэш или нет, в случаеtrue
необходимо указать явно.getDeadline
: функция, возвращающая количество миллис, после которого данные о состоянии должны быть удалены (по запросу).hash
: функция, которая получаетargs
иpayload
запуска и вычисляет хэш кеша.persist
: Если вы хотите сохранить свой кеш, используйте эту функцию, которая вызывается каждый раз при изменении кеша со всеми записями.load
: функция, которая изначально загружает кэш (может быть асинхронной).onCacheLoads
: Когда кеш загружается асинхронно, вы можете прикрепить это событие, которое, например, изменит состояние.
Примечание. Конфигурация состояния initialValue
получает кеш, поэтому, если вы можете синхронно загрузить кеш, вы можете загрузить из него свое состояние.
useSource
и useProducer
Судя по их именам, эти хуки говорят сами за себя и записываются в библиотеке следующим образом:
Итак, теперь это просто разные имена… (в прошлом они были другими, с одним и тем же API, но с другой реализацией).
Заключение
Если вы думаете о варианте использования, который я не рассмотрел в предыдущих примерах, сообщите мне, чтобы мы могли его добавить.
Далее давайте посмотрим, как работает объект source
и как мы можем его использовать.