Store API
import { type Store, type StoreWritable, createStore } from "effector";
const $store = createStore();
Store — это объект, который хранит значение состояния. Обновление стора происходит когда новое значение не равно (!==
) текущему, а также когда не равно undefined
(если в конфигурации стора не указан skipVoid:false
). Стор является Unit. Некоторые сторы могут быть производными.
Если вы еще не знакомы как работать со стором, то добро пожаловать сюда.
Интерфейс стора
Доступные методы и свойства стора:
Метод/Свойство | Описание |
---|---|
map(fn) | Создает новый производный стор |
on(trigger, reducer) | Обновление стейта c помощью reducer , когда вызван trigger |
watch(watcher) | Вызывает функцию watcher каждый раз, когда стор обновляется |
reset(...triggers) | Метод для сброса к начальному состоянию |
off(trigger) | Удаляет подписку на указанный триггер |
updates() | Событие срабатывающие при обновление стора |
reinit() | Событие для реинициализации стора |
shortName | ID или короткое имя store |
defaultState | Начальное состояние стора |
getState() | Возвращает текущий стейт |
Иммутабельность
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)
Принимает функцию fn
и возвращает производный стор, который автоматически обновляется, когда исходный стор изменяется.
- Формула
$source.map(fn, config?);
- Тип
const $derived = $source.map<T>(
fn: (value: SourceValue) => T,
config?: {
skipVoid?: boolean
}
): Store<T>
- Примеры
Базовое использование:
import { createEvent, createStore } from "effector";
const changed = createEvent<string>();
const $title = createStore("");
const $titleLength = $title.map((title) => title.length);
$title.on(changed, (_, newTitle) => newTitle);
$titleLength.watch((length) => {
console.log("new length", length);
});
changed("hello");
changed("world");
changed("hello world");
Вторым аргументом можно передать объект конфига со значением skipVoid:false
, тогда стор сможет принимать undefined
значения:
const $titleLength = $title.map((title) => title.length, { skipVoid: false });
- Детальное описание
Метод map
вызывает переданную функцию fn
с состоянием исходного стора в аргументе, каждый раз когда оригинальный стор обновляется.
Результат выполнения функции используется как значение стора.
- Возвращаемое значение
Возвращает новый производный стор.
.on(trigger, reducer)
Обновляет состояние используя reducer, при срабатывании trigger
.
- Формула
$store.on(trigger, reducer);
- Тип
$store.on<T>(
trigger: Unit<T> | Unit<T>[]
reducer: (state: State, payload: T) => State | void
): this
- Примеры
import { createEvent, createStore } from "effector";
const $counter = createStore(0);
const incrementedBy = createEvent<number>();
$counter.on(incrementedBy, (value, incrementor) => value + incrementor);
$counter.watch((value) => {
console.log("updated", value);
});
incrementedBy(2);
incrementedBy(2);
- Возвращаемое значение
Возвращает текущий стор.
.watch(watcher)
Вызывает функцию watcher
каждый раз, когда стор обновляется.
- Формула
const unwatch = $store.watch(watcher);
- Тип
$store.watch(watcher: (state: State) => any): Subscription
- Примеры
import { createEvent, createStore } from "effector";
const add = createEvent<number>();
const $store = createStore(0);
$store.on(add, (state, payload) => state + payload);
$store.watch((value) => console.log(`current value: ${value}`));
add(4);
add(3);
- Возвращаемое значение
Возвращает функцию для отмены подписки.
.reset(...triggers)
Сбрасывает состояние стора до значения по умолчанию при срабатывании любого trigger
.
- Формула
$store.reset(...triggers);
- Тип
$store.reset(...triggers: Array<Unit<any>>): this
- Примеры
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);
- Тип
$store.off(trigger: Unit<any>): this
- Примеры
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
Событие срабатывающие при обновление стора.
- Примеры
import { createStore, is } from "effector";
const $clicksAmount = createStore(0);
is.event($clicksAmount.updates); // true
$clicksAmount.updates.watch((amount) => {
console.log(amount);
});
- Возвращаемое значение
Производное событие, представляющее обновления данного стора.
.reinit
Событие для реинициализации стора.
- Примеры
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
Cтроковое свойство, которое содержит ID или короткое имя стора.
- Примеры
const $store = createStore(0, {
name: "someName",
});
console.log($store.shortName); // someName
- Возвращаемое значение
ID или короткое имя store.
.defaultState
Свойство, которое содержит значение состояния по умолчанию стора.
- Пример
const $store = createStore("DEFAULT");
console.log($store.defaultState === "DEFAULT"); // true
- Возвращаемое значение
Значение состояния по умолчанию.
Вспомогательные методы
.getState()
Метод, который возвращает текущее состояние стора.
getState()
не рекомендуется использовать в бизнес-логике - лучше передавать данные через sample
.
- Примеры
import { createEvent, createStore } from "effector";
const add = createEvent<number>();
const $number = createStore(0).on(add, (state, data) => state + data);
add(2);
add(3);
console.log($number.getState());
- Возвращаемое значение
Текущее состояние стора.
Связанные API
createStore
- Создает новый сторcombine
- Комбинирует несколько сторов и возращает новый производный сторsample
- Ключевой оператор для построения связей между юнитамиcreateEvent
- Создает событияcreateEffect
- Создает эффекты
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.