Skip to content

Начало работы

Сначала установите @virentia/core: с его помощью вы будете описывать модель состояния.

sh
pnpm add @virentia/core

@virentia/react нужен только там, где модель рендерится в React. @virentia/effector нужен только для compatibility layer с API в стиле Effector.

Создание маленькой модели

Начните с состояния, которое приложение должно помнить в этом сценарии, а потом назовите события, через которые это состояние меняется. У счетчика состояние — текущее число. События — incremented и reset: число увеличили и счетчик сбросили.

ts
import { event, reaction, store } from "@virentia/core";

export function createCounterModel() {
  const incremented = event<number>();
  const reset = event<void>();
  const count = store(0);

  reaction({
    on: incremented,
    run(amount) {
      count.value += amount;
    },
  });

  reaction({
    on: reset,
    run() {
      count.value = 0;
    },
  });

  return { count, incremented, reset };
}

Здесь важнее не синтаксис, а разделение ответственности. Сторы помнят состояние. События сообщают о том, что произошло. Реакции держат правила, которые связывают события с изменениями состояния. Такая модель расширяется спокойнее, чем один большой объект с набором технических методов изменения состояния.

Состояние в scope

Определение модели можно переиспользовать. Scope хранит значения для конкретного экземпляра: приложения, теста, серверного запроса или экрана, который остается в памяти.

ts
const model = createCounterModel();
const appScope = scope();

await allSettled(model.incremented, {
  scope: appScope,
  payload: 2,
});

scoped(appScope, () => {
  console.log(model.count.value); // 2
});

Используйте allSettled, когда событие или эффект должны выполниться в конкретном scope: в тесте, серверном загрузчике, команде или адаптере. Используйте scoped(scope, fn), когда обычный код должен читать или писать сторы, в том числе после await. Если callback-функцию позже вызовет внешняя библиотека, сохраните ее через scoped(scope).wrap(fn).

UI-библиотеки

Модель, написанная с помощью @virentia/core, не зависит от UI-слоя. Как подключить ее к React, читайте в разделе @virentia/react. Другие UI-адаптеры должны строиться по тому же принципу: UI выбирает scope, а модель остается обычным кодом Virentia.

Следующие разделы

Перед API-страницами лучше прочитать идеологию. Там объясняется, почему Virentia разделяет сторы, события, эффекты, реакции, скоупы и владельцев.