В этом посте вы узнаете, как использовать набор инструментов асинхронного состояния для управления состоянием с помощью реакции с помощью обработчика состояния useAsyncState.

Этот пост является частью следующей серии постов в блоге:

  1. async-states: библиотека управления состоянием
  2. асинхронные состояния: использование реакции
  3. асинхронные состояния: исходный объект
  4. асинхронные состояния: производитель
  5. асинхронные состояния: расширенные концепции
  6. асинхронные состояния: vs. response-query vs redux vs recoil
  7. реагировать-асинхронные-состояния: 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 и как мы можем его использовать.