Моделирование поведения веб-компонентов с помощью XState

XState — это библиотека для создания, интерпретации и выполнения конечных автоматов состояния и диаграмм состояний.

Конечные автоматы состояний (или сокращенно «автоматы состояний») и диаграммы состояний — это визуальный язык, используемый для описания состояний процесса. Возможно, вы уже использовали подобные диаграммы в прошлом для проектирования потоков пользователей, планирования баз данных или создания архитектуры приложений. Они идеально подходят для моделирования поведения веб-компонентов.

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

В этом посте мы рассмотрим, как моделировать поведение в веб-компонентах с помощью машин состояний и диаграмм состояний в FicusJS.

Машины состояний и диаграммы состояний

В чем разница между машинами состояний и диаграммами состояний? Понимание машин состояний почти то же самое, что и понимание диаграмм состояний. Statecharts — это «старший брат» машин состояний и по сути является машиной состояний, которая позволяет любому состоянию включать в себя больше машин в иерархическом порядке.

Преимущества использования машин состояний

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

  • Поведение (когда все происходит) отделено от фактического компонента (что происходит).
  • Они приводят к меньшему количеству ошибок, чем традиционный код.
  • По мере роста сложности вашей программы диаграммы состояний хорошо масштабируются.
  • Вы исследуете все возможные состояния вашей программы.

Проектирование машин состояний

Первым шагом в проектировании машин состояний является использование доски или ручки и бумаги и запись возможных состояний компонента, который вы хотите создать. Это важная часть процесса, в которой должны участвовать UX-дизайнеры, владельцы продукта и разработчики. Обсуждение поведения компонента и запись всех состояний помогает заранее определить все возможности.

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

Пример

Мы собираемся создать визуальное изображение простой машины состояний. Это модель простого переключателя вкл/выкл.

Чтобы просмотреть визуальную модель и взаимодействовать с ней, посетите сайт https://stately.ai/viz/04fcf47e-df9f-4f78-b3b9-4826c24b2df9.

Визуальная модель — это имитация, которая помогает уточнить поведение через определение состояний и переходов машины состояний.

  • Она состоит из двух состояний, «включено» и «выключено». Таким образом, в любой момент времени машина может находиться ровно в одном из двух состояний. Другими словами, переходы между состояниями мгновенны.
  • Событие «щелчок» вызывает переход между состояниями.
  • Когда машина переходит в состояние «включено», возникает побочный эффект. Включается свет.
  • Когда машина выходит из состояния «включено», возникает другой побочный эффект. Свет выключается.

Определение автомата выглядит следующим образом:

{
  id: "switch",
  initial: "off",
  states: {
    off: {
      on: {
        FLICK: {
          target: "on",
          actions: "turnLightOn",
        },
      },
    },
    on: {
      on: {
        FLICK: {
          target: "off",
          actions: "turnLightOff",
        },
      },
    },
  },
}
Вход в полноэкранный режим Выход из полноэкранного режима

Создание автомата состояний

Чтобы создать машину состояний, вы импортируете функцию createMachine и передаете ей объект определения машины.

FicusJS украшает пакет @xstate/fsm для предоставления дополнительных возможностей, таких как расширенные геттеры состояний. Вы также можете использовать полную библиотеку XState с FicusJS, более подробную информацию смотрите в документации по машине состояний.

import { createMachine } from 'https://cdn.skypack.dev/@ficusjs/state@3/xstate-service'

const machine = createMachine({
  id: "switch",
  context: { bulb: 'off' },
  initial: "off",
  states: {
    off: {
      on: {
        FLICK: {
          target: "on",
          actions: "turnLightOn",
        },
      },
    },
    on: {
      on: {
        FLICK: {
          target: "off",
          actions: "turnLightOff",
        },
      },
    },
  },
})
Вход в полноэкранный режим Выход из полноэкранного режима

Создание побочных эффектов

Наша машина состояний имеет два побочных эффекта. Это действия, которые вызываются при получении перехода.

Действия передаются как опции в функцию createMachine.

import { createMachine } from 'https://cdn.skypack.dev/@ficusjs/state@3/xstate-service'

const definition = {
  id: "switch",
  context: { bulb: 'off' },
  initial: "off",
  states: {
    off: {
      on: {
        FLICK: {
          target: "on",
          actions: "turnLightOn",
        },
      },
    },
    on: {
      on: {
        FLICK: {
          target: "off",
          actions: "turnLightOff",
        },
      },
    },
  },
}

const options = {
  actions: {
    turnLightOn: assign({
      bulb: 'on'
    }),
    turnLightOff: assign({
      bulb: 'off'
    })
  }
}

const machine = createMachine(definition, options)
Войти в полноэкранный режим Выход из полноэкранного режима

Интерпретируемые машины состояний

Мы можем использовать интерпретируемую машину состояний для отслеживания состояния. Чтобы создать интерпретируемую машину состояний, передайте машину, созданную с помощью createMachine, в функцию interpret. Результат работы функции interpret называется сервисом (запущенный экземпляр машины).

const machine = createMachine(definition, options)
const service = interpret(machine)
Вход в полноэкранный режим Выход из полноэкранного режима

Использование компонента

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

Чтобы передать сервис компоненту, используйте расширение компонента withXStateService.

import { html, renderer } from 'https://cdn.skypack.dev/@ficusjs/renderers@5/uhtml'
import { createCustomElement, withXStateService } from 'https://cdn.skypack.dev/ficusjs@5'

createCustomElement(
  'switch-state-machine',
  withXStateService(service, {
    renderer,
    onChange () {
      this.fsm.send('FLICK')
    },
    render () {
    }
  })
)
Вход в полноэкранный режим Выход из полноэкранного режима

Результат

Следующий Codepen представляет собой пример реализации машины состояний переключателя, используемой для включения/выключения лампочки.

Резюме

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

Машины состояний отлично подходят, если вам нужно тщательно контролировать поток приложения. Если вы начинаете использовать XState, это не значит, что все должно жить внутри машины состояний. Некоторые вещи нужно контролировать на локальном уровне внутри компонента, а не на глобальном уровне внутри машины состояний. Это относится как к состоянию, так и к побочным эффектам.

Создавайте меньшие машины состояний, а не одну огромную машину состояний. Программирование — это композиция, создание больших вещей из меньших — а машины состояний хорошо компонуются.

Оцените статью
devanswers.ru
Добавить комментарий