import { type Store, type StoreWritable } from "effector";
Store — это объект, который хранит значение состояния. Стор обновляется, когда получает значение, которое не равно (!==
) текущему и не равно undefined
. Стор является Unit. Некоторые сторы могут быть производными.
Иммутабельность
Store в effector иммутабелен. Это значит, что обновления в нём будут происходить только если в функции-обработчике (например combine
, sample
или on
) вернуть новый объект
Например, прежде чем использовать методы массива, нужно создать новую ссылку на него. Как правильно:
$items.on(addItem, (items, newItem) => {
const updatedItems = [...items];
// ✅ метод .push вызывается на новом массиве
updatedItems.push(newItem);
return updatedItems;
});
Так делать нельзя, обновления стора не произойдёт
$items.on(addItem, (items, newItem) => {
// ❌ ошибка! Ссылка на массив осталась та же, обновления стора не произойдёт
items.push(newItem);
return items;
});
Обновление объектов происходит аналогичным образом
Сторы в effector должен быть размером как можно меньше, чтобы отвечать за конкретную часть в бизнес логике, в отличии от например redux стора, который имеет тенденцию к тому чтобы держать рядом всё и сразу. Когда состояние атомарное, то необходимости в спредах объектов становится меньше. Однако, если возникает потребность часто обновлять сильно вложенные данные, для обновления состояния допустимо применять immer чтобы упростить повторяющийся код
Методы стора
.map(fn)
Создает производный стор. Он вызывает переданную функцию с состоянием, когда оригинальный стор обновляется, и использует результат для обновления производного стора.
Формула
const $second = $first.map(fn);
Аргументы
fn
(Function): Функция, которая принимаетstate
и возвращает новое состояние для производного стора.config
(Object): Необязательная конфигурация.
Возвращает
DerivedStore: Новый производный стор.
Примеры
Основной пример
import { createEvent, createStore } from "effector";
const changed = createEvent();
const $title = createStore("").on(changed, (_, newTitle) => newTitle);
const $length = $title.map((title) => title.length);
$length.watch((length) => {
console.log("new length", length);
});
changed("hello");
changed("world");
changed("hello world");
Пропускать пустые значения
const $length = $title.map((title) => title.length, { skipVoid: false });
.on(trigger, reducer)
Обновляет состояние, когда trigger
срабатывает, используя reducer.
Формула
$store.on(trigger, reducer);
Аргументы
trigger
: Event, Effect или другой Store.reducer
: Reducer: Функция, которая принимаетstate
иparams
и возвращает новое состояние.
Возвращает
Store: Текущий стор.
Примеры
Основной пример
import { createEvent, createStore } from "effector";
const $store = createStore(0);
const changed = createEvent();
$store.on(changed, (value, incrementor) => value + incrementor);
$store.watch((value) => {
console.log("updated", value);
});
changed(2);
changed(2);
.watch(watcher)
Вызывает функцию watcher
каждый раз, когда стор обновляется.
Формула
const unwatch = $store.watch(watcher);
Аргументы
watcher
: Watcher: Функция-наблюдатель, которая принимает текущее состояние стора в качестве первого аргумента.
Возвращает
Subscription: Функция для отмены подписки.
Примеры
Основной пример
import { createEvent, createStore } from "effector";
const add = createEvent();
const $store = createStore(0).on(add, (state, payload) => state + payload);
$store.watch((value) => console.log(`current value: ${value}`));
add(4);
add(3);
.reset(...triggers)
Сбрасывает состояние стора до значения по умолчанию.
Формула
$store.reset(...triggers);
Аргументы
triggers
: ((Event | Effect | Store)[]): любое количество Events, Effects или Stores.
Возвращает
Store: Текущий стор.
Примеры
Основной пример
import { createEvent, createStore } from "effector";
const increment = createEvent();
const reset = createEvent();
const $store = createStore(0)
.on(increment, (state) => state + 1)
.reset(reset);
$store.watch((state) => console.log("changed", state));
increment();
increment();
reset();
.off(trigger)
Удаляет reducer для указанного trigger
.
Формула
$store.off(trigger);
Аргументы
trigger
: Event, Effect или Store.
Возвращает
Store: Текущий стор.
Примеры
Основной пример
import { createEvent, createStore, merge } from "effector";
const changedA = createEvent();
const changedB = createEvent();
const $store = createStore(0);
const changed = merge([changedA, changedB]);
$store.on(changed, (state, params) => state + params);
$store.off(changed);
Свойства стора
.updates
Возвращает
Event: Событие, представляющее обновления данного стора.
Пример
import { createStore, is } from "effector";
const $clicksAmount = createStore(0);
is.event($clicksAmount.updates); // true
$clicksAmount.updates.watch((amount) => {
console.log(amount);
});
.reinit
Возвращает
EventCallable: Событие, которое может реинициализировать стор до значения по умолчанию.
Пример
import { createStore, createEvent, sample, is } from "effector";
const $counter = createStore(0);
is.event($counter.reinit);
const increment = createEvent();
$counter.reinit();
console.log($counter.getState());
.shortName
Возвращает
(string
): ID или короткое имя store.
.defaultState
Возвращает
(State
): Значение состояния по умолчанию.
Пример
const $store = createStore("DEFAULT");
console.log($store.defaultState === "DEFAULT");
Вспомогательные методы
.getState()
Возвращает текущее состояние стора.
Возвращает
(State
): Текущее состояние стора.
Пример
import { createEvent, createStore } from "effector";
const add = createEvent();
const $number = createStore(0).on(add, (state, data) => state + data);
add(2);
add(3);
console.log($number.getState());
Стор только для чтения
TBD
Типы
import { type StoreValue } from "effector";
StoreValue<S>
Извлекает тип значения Store
или StoreWritable
.
const $store: Store<Value>;
type Value = StoreValue<typeof $store>;
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.