React

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

Базовая единица в FAST — класс элемента, который наследуется от FASTElement. Такой класс описывает поведение компонента, его свойства и методы.

import { FASTElement, html, css } from "@microsoft/fast-element";

const template = html<MyElement>`
  <div class="container">
    <h1>${x => x.title}</h1>
    <button @click=${x => x.increment()}>Click Me (${x => x.count})</button>
  </div>
`;

const styles = css`
  .container {
    padding: 10px;
    border: 1px solid #ccc;
  }
  button {
    cursor: pointer;
  }
`;

export class MyElement extends FASTElement {
  title = "Пример FAST Element";
  count = 0;

  increment() {
    this.count++;
  }
}

FASTElement.define({
  name: "my-element",
  template,
  styles,
  elementClass: MyElement
});

Ключевые моменты:

  • template — HTML-шаблон с поддержкой реактивных привязок через стрелочные функции.
  • @click=${x => x.increment()} — декларативная привязка событий.
  • FASTElement.define — регистрация компонента как стандартного Web Component.

Свойства и реактивность

Свойства компонентов FAST могут быть обычными полями класса, но для полной реактивности рекомендуется использовать @observable:

import { FASTElement, observable } from "@microsoft/fast-element";

export class Counter extends FASTElement {
  @observable count = 0;

  increment() {
    this.count++;
  }
}

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

import { attr, FASTElement, observable } from "@microsoft/fast-element";

export class UserCard extends FASTElement {
  @attr name;
  @observable age;
}
  • @attr — синхронизация свойства с атрибутом DOM.
  • @observable — реактивное свойство, не обязательно отражается в DOM.

События

FAST поддерживает кастомные события с декларативной отправкой через dispatchEvent:

this.dispatchEvent(new CustomEvent("incremented", { detail: this.count }));

В шаблоне можно подписаться на события через @:

<button @click=${x => x.handleClick()}>Click</button>

Компоненты в стиле React

Хотя FAST строится на Web Components, многие концепции из React имеют аналоги:

  • JSX-подобная привязка: шаблоны FAST используют функции для реактивного отображения данных.
  • Состояние: @observable соответствует useState в React.
  • Композиция: компоненты FAST могут содержать другие компоненты как теги:
const template = html<AppRoot>`
  <my-element title="Привет" @incremented=${x => console.log(x.detail)}></my-element>
`;
  • Жизненный цикл: методы connectedCallback, disconnectedCallback, attributeChangedCallback доступны напрямую, аналогично хукам React.

Стиль и CSS

FAST поддерживает Shadow DOM и scoped CSS. Для локального стиля компонента используется объект css:

const styles = css`
  :host {
    display: block;
    font-family: sans-serif;
  }

  h1 {
    color: darkblue;
  }
`;
  • :host — селектор для корневого элемента компонента.
  • Все стили изолированы внутри компонента, что исключает конфликты глобальных стилей.

Шаблонные директивы

FAST предоставляет директивы шаблонов, похожие на условные и циклические рендеры в React:

  • if.bind — условное отображение:
<div ${x => x.isVisible ? html`<p>Виден</p>` : null}></div>
  • repeat — повторение коллекции:
import { repeat } from "@microsoft/fast-element";

const listTemplate = html<MyElement>`
  <ul>
    ${repeat(x => x.items, html<Item>`<li>${i => i.name}</li>`)}
  </ul>
`;
  • ref — ссылка на DOM-элемент:
<input ${x => x.ref('inputRef')}>

Интеграция с React

FAST Element легко использовать внутри React через Web Components:

import React from "react";
import "./my-element.js";

function App() {
  return <my-element title="FAST внутри React"></my-element>;
}
  • Привязка событий через стандартные DOM события: onIncremen ted={(e) => console.log(e.detail)}
  • Пропсы передаются как атрибуты.

Это позволяет постепенно интегрировать FAST в существующие React-приложения.


Расширение и наследование

Компоненты FAST поддерживают наследование классов:

class BaseElement extends FASTElement {
  baseProperty = "base";
}

class ExtendedElement extends BaseElement {
  extendedProperty = "extended";
}
  • Можно переопределять методы и свойства.
  • Шаблоны и стили наследуются или комбинируются через compose.

Асинхронные данные

FAST поддерживает работу с асинхронными данными через промисы и реактивные свойства:

export class AsyncList extends FASTElement {
  @observable items = [];

  async fetchData() {
    const response = await fetch("/api/items");
    this.items = await response.json();
  }

  connectedCallback() {
    super.connectedCallback();
    this.fetchData();
  }
}
  • При обновлении items автоматически обновляется привязанный шаблон.
  • Реактивность работает без дополнительных хуков.

Оптимизация производительности

  • Обновления DOM только при изменении данных.
  • Lazy rendering через директивы if.bind и repeat.
  • Shadow DOM изолирует стили и уменьшает перерисовку глобальных элементов.

Использование этих механизмов делает FAST Element эффективной альтернативой React при создании высокопроизводительных веб-компонентов.