Skip to content

Модели и компоненты

React-компонентам часто нужно состояние, которое зависит от props и исчезает вместе с компонентом. В Virentia такое состояние все равно должно оставаться моделью ядра. React-пакет только создает ее в нужный момент и готовит к рендеру.

Фабрики моделей

Фабрика модели получает ModelContext. Поле props — это стор, поэтому реакции могут читать актуальные props без пересоздания модели на каждый рендер.

tsx
function createCounterModel({ props }: ModelContext<{ step: number }>) {
  const clicked = event<void>();
  const count = store(0);

  reaction({
    on: clicked,
    run() {
      count.value += props.step;
    },
  });

  return { clicked, count };
}

Используйте фабрику, когда модель принадлежит одному экземпляру компонента, зависит от props или нуждается в юнитах жизненного цикла вроде mounted и unmounted.

useModel

useModel создает модель один раз для экземпляра компонента и подготавливает ее для рендера. Сторы становятся значениями. События и эффекты становятся callback-функциями, привязанными к текущему scope.

tsx
export function Counter(props: { step: number }) {
  const model = useModel(createCounterModel, props);

  return <button onClick={() => model.clicked()}>{model.count}</button>;
}

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

component

component упаковывает тот же паттерн в одно объявление: создать модель, поддерживать актуальные props, отправить события монтирования и размонтирования, подготовить модель и отрендерить view.

tsx
export const Counter = component({
  model: createCounterModel,
  view({ model }) {
    return <button onClick={() => model.clicked()}>{model.count}</button>;
  },
});

Используйте component, когда модель принадлежит view. Используйте useModel, когда нужно вручную встроить модель в уже существующий компонент.

Юниты жизненного цикла

Фабрики получают mounted, unmounted и mounts. Используйте их для логики модели, которая должна реагировать на жизнь UI: загрузить данные при mount, поставить работу на паузу, когда размонтирован последний экземпляр, или понять, сколько view сейчас используют кешированную модель.

Юниты жизненного цикла — это часть модели, а не React-эффекты, замаскированные под код модели. Предпочитайте их, когда результат должен тестироваться как часть модели.