import { type Store, type StoreWritable } from "effector";
Store — это объект, который хранит значение состояния. Store обновляется, когда получает значение, которое не равно (!==
) текущему и не равно undefined
. Store является Unit. Некоторые stores могут быть derived.
Иммутабельность
Store в effector иммутабелен. Это значит, что обновления в нём будут происходить только если в функции-обработчике (например combine
, sample
или on
) вернуть новый объект
Например, прежде чем использовать методы массива, нужно создать новую ссылку на него. Как правильно:
$items.on(addItem, (items, newItem) => {
const updatedItems = [...items];
// ✅ метод .push вызывается на новом массиве
updatedItems.push(newItem);
return updatedItems;
});
Так делать нельзя, обновления стора не произойдёт
$items.on(addItem, (items, newItem) => {
// ❌ ошибка! Ссылка на массив осталась та же, обновления store не произойдёт
items.push(newItem);
return items;
});
Обновление объектов происходит аналогичным образом
Store в effector должен быть размером как можно меньше, чтобы отвечать за конкретную часть в бизнес логике, в отличии от например redux, store которого имеет тенденцию к тому чтобы держать рядом всё и сразу. Когда состояние атомарное, то необходимости в спредах объектов становится меньше. Однако, если возникает потребность часто обновлять сильно вложенные данные, для обновления состояния допустимо применять immer чтобы упростить повторяющийся код
Методы Store
.map(fn)
Создает производный store. Он вызывает переданную функцию с состоянием, когда оригинальный store обновляется, и использует результат для обновления производного store.
Формула
const $second = $first.map(fn);
Аргументы
fn
(Function): Функция, которая принимаетstate
и возвращает новое состояние для производного store.config
(Object): Необязательная конфигурация.
Возвращает
DerivedStore: Новый производный store.
Примеры
Основной пример
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: Текущий 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
каждый раз, когда store обновляется.
Формула
const unwatch = $store.watch(watcher);
Аргументы
watcher
: Watcher: Функция-наблюдатель, которая принимает текущее состояние store в качестве первого аргумента.
Возвращает
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 до значения по умолчанию.
Формула
$store.reset(...triggers);
Аргументы
triggers
: ((Event | Effect | Store)[]): любое количество Events, Effects или Stores.
Возвращает
Store: Текущий 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: Текущий 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);
Свойства Store
.updates
Возвращает
Event: Событие, представляющее обновления данного store.
Пример
import { createStore, is } from "effector";
const $clicksAmount = createStore(0);
is.event($clicksAmount.updates); // true
$clicksAmount.updates.watch((amount) => {
console.log(amount);
});
.reinit
Возвращает
EventCallable: Событие, которое может реинициализировать store до значения по умолчанию.
Пример
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()
Возвращает текущее состояние store.
Возвращает
(State
): Текущее состояние store.
Пример
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());
Только для чтения store
TBD
Типы
import { type StoreValue } from "effector";
StoreValue<S>
Извлекает тип значения Store
или StoreWritable
.
const $store: Store<Value>;
type Value = StoreValue<typeof $store>;
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.