Store API (Store Unit)
import { type Store, type StoreWritable, createStore } from "effector";
const $store = createStore();
A Store is an object that holds the state value. The store updates when the new value is not strictly equal (!==
) to the current one and is not undefined
(unless the store is configured with skipVoid: false
). A store is a Unit. Some stores can be derived.
If you’re not yet familiar with how to work with a store, feel free to start here.
Store Interface
Available store methods and properties:
Method/Property | Description |
---|---|
map(fn) | Creates a new derived store |
on(trigger, reducer) | Updates state via a reducer when the trigger is fired |
watch(watcher) | Calls the watcher function every time the store is updated |
reset(...triggers) | Resets the store to its initial state |
off(trigger) | Removes the subscription to the specified trigger |
updates() | Event that fires when the store updates |
reinit() | Event to reinitialize the store |
shortName | ID or short name of the store |
defaultState | Initial state of the store |
getState() | Returns the current state |
Immutability
A store in effector is immutable. This means that updates will only occur if the handler function (such as combine
, sample
, or on
) returns a new object.
For example, before using array methods, you need to create a new reference to it. Here’s how to do it correctly:
$items.on(addItem, (items, newItem) => {
const updatedItems = [...items];
// ✅ .push method is called on a new array
updatedItems.push(newItem);
return updatedItems;
});
This approach should not be used, as the store will not be updated:
$items.on(addItem, (items, newItem) => {
// ❌ Error! The array reference remains the same, the store will not be updated
items.push(newItem);
return items;
});
Updating objects works in a similar way.
A store in effector should be as small as possible, responsible for a specific part of the business logic, unlike, for example, Redux, whose store tends to hold everything together. When the state is atomic, the need for spreading objects becomes less frequent. However, if there is a need to frequently update deeply nested data, it is acceptable to use immer to simplify repetitive code when updating the state.
Store Methods
.map(fn)
Accepts a function fn
and returns a derived store that automatically updates when the original store changes.
- Formulae
$source.map(fn, config?);
- Type
const $derived = $source.map<T>(
fn: (value: SourceValue) => T,
config?: {
skipVoid?: boolean
}
): Store<T>
- Examples
Basic usage:
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");
You can pass a config object with skipVoid: false
to allow the store to accept undefined
:
const $titleLength = $title.map((title) => title.length, { skipVoid: false });
- Detailed Description
The map
method runs the function fn
with the current store state as input every time the original store updates.
The return value becomes the new state of the derived store.
- Returns
Returns a new derived store.
.on(trigger, reducer)
Updates state using a reducer when the trigger
is fired.
- Formulae
$store.on(trigger, reducer);
- Type
$store.on<T>(
trigger: Unit<T> | Unit<T>[]
reducer: (state: State, payload: T) => State | void
): this
- Examples
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);
- Returns
Returns the current store.
.watch(watcher)
Calls the watcher
function whenever the store updates.
- Formulae
const unwatch = $store.watch(watcher);
- Type
$store.watch(watcher: (state: State) => any): Subscription
- Examples
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);
- Returns
Returns a subscription cancellation function.
.reset(...triggers)
Resets the store to its default value when any of the triggers
fire.
- Formulae
$store.reset(...triggers);
- Type
$store.reset(...triggers: Array<Unit<any>>): this
- Examples
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();
- Returns
Returns the current store.
.off(trigger)
Removes the reducer for the specified trigger
.
- Formulae
$store.off(trigger);
- Type
$store.off(trigger: Unit<any>): this
- Examples
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);
- Returns
Returns the current store.
Store Properties
.updates
An event that fires on every store update.
- Examples
import { createStore, is } from "effector";
const $clicksAmount = createStore(0);
is.event($clicksAmount.updates); // true
$clicksAmount.updates.watch((amount) => {
console.log(amount);
});
- Returns
A derived event representing the store’s updates.
.reinit
Event to reinitialize the store to its default state.
- Examples
import { createStore, createEvent, sample, is } from "effector";
const $counter = createStore(0);
is.event($counter.reinit);
const increment = createEvent();
$counter.reinit();
console.log($counter.getState());
- Returns
An event that reinitializes the store.
.shortName
A string property containing the store’s ID or short name.
- Examples
const $store = createStore(0, {
name: "someName",
});
console.log($store.shortName); // someName
- Returns
The store’s ID or short name.
.defaultState
The store’s default state value.
- Example
const $store = createStore("DEFAULT");
console.log($store.defaultState === "DEFAULT"); // true
- Returns
The default state value.
Utility Methods
.getState()
Returns the current state of the store.
Using getState()
in business logic is not recommended — it’s better to pass data through sample
.
- Examples
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());
- Returns
The current state of the store.
Related APIs
createStore
– Creates a new storecombine
– Combines multiple stores into a derived storesample
– A core operator for connecting unitscreateEvent
– Creates an eventcreateEffect
– Creates an effect