Store
Store is an object that holds the state value. Store is getting updates when receives a value that is not equal (!==
) to current one and to undefined
. Store is Unit. Some stores can be derived.
Store Methods
map(fn: (state: State, lastState?: T) => T, firstState: T)
Since effector 21.8.0 the second argument of fn
and firstState
are deprecated, use updateFilter
or explicit createStore
instead.
Creates a derived store. It will call a provided function with the state, when the original store updates, and will use the result to update the derived store
Formulae
const $second = $first.map(fn)
- When
$first
store is updated, callfn
with new state and previous state - Next update
$second
store with result offn()
call and trigger all subscribers
Arguments
fn
(Function): Function that receivesstate
andlastState?
and returns a new state for the derived store
If the function returns an old state or if it returns undefined
, the new store will not be updated.
Returns
DerivedStore: New derived store
Example
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)
})
// => new length 0
changed('hello')
// => new length 5
changed('world')
// no reaction
changed('hello world')
// => new length 11
on(trigger, reducer)
Updates state when trigger
is triggered by using reducer
. For each trigger, last installed reducer will override previous reducers (useful for dynamic behavior).
Formulae
$store.on(trigger, reducer)
- When
trigger
is triggered, callreducer
with payload of thetrigger
and data of$store
- Next update
$store
with result ofreducer
call and trigger all subscribers
Arguments
trigger
Event, Effect or another Storereducer
Reducer: Function that receivesstate
andparams
and returns a new state, should be pure. A store cannot hold anundefined
value. If a reducer function returnsundefined
, the store will not be updated.state
: Current state of storeparams
: Parameters passed to event call
Returns
Store: Current store
Example
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)
})
// => updated 0
changed(2)
// => updated 2
changed(2)
// => updated 4
on(triggers[], reducer)
effector 20.15.0
Updates state when any from triggers
is triggered by using reducer
.
Formulae
$store.on([triggerA, triggerB, ...], reducer)
- When
triggerA
ortriggerB
is triggered, callreducer
with payload of thetriggerA
ortriggerB
and data of$store
- Next update
$store
with result ofreducer
call and trigger all subscribers - Any count of triggers can be passed to
triggers
Arguments
triggers
array of Event, Effect or Storereducer
Reducer: Function that receivesstate
andparams
and returns a new state, should be pure. A store cannot hold anundefined
value. If a reducer function returnsundefined
, the store will not be updated.state
: Current state of storepayload
: Value passed to event/effect call, or source if it passed as trigger
Returns
Store: Current store
Example
import {createEvent, createStore} from 'effector'
const changedA = createEvent()
const changedB = createEvent()
const $store = createStore(0)
$store.on([changedA, changedB], (value, incrementor) => value + incrementor)
$store.watch(value => {
console.log('updated', value)
})
changedA(2)
// => updated 2
changedB(2)
// => updated 4
// You can unsubscribe from any trigger
$store.off(changedA)
watch(watcher)
Call watcher
function each time when store is updated.
Formulae
const unwatch = $store.watch(watcher)
- On initialize and each
$store
update, callwatcher
with the new state of$store
- When
unwatch
is called, stop callingwatcher
Arguments
watcher
(Watcher): Watcher function that receives current store state as the first argument
Returns
Subscription: Unsubscribe function
Example
const add = createEvent()
const $store = createStore(0).on(add, (state, payload) => state + payload)
$store.watch(value => console.log(`current value: ${value}`))
// => current value: 0
add(4)
// => current value: 4
add(3)
// => current value: 7
watch(trigger, watcher)
Since effector 23.0.0 the second argument of watch
is deprecated, use sample
to run a function after clock
field trigerred instead.
Run watcher
only when trigger
event triggered.
Formulae
const unwatch = $store.watch(trigger, watcher)
- On each
$store
update with passedtrigger
, callwatcher
with the new state of$store
and payload fromtrigger
- When
unwatch
is called, stop callingwatcher
Arguments
trigger
Event, Effect or Store: Trigger, which leads to call ofwatcher
watcher
(Function): Function that receives current store state as the first argument and payload of trigger as the second argument.
Returns
Subscription: Unsubscribe function
Example 1
.watch
trigger watcher
when foo
is executed, because foo
is explicitly passed to watch
.
First argument of watcher
is a state value, second is an event value.
import {createEvent, createStore} from 'effector'
const foo = createEvent()
const bar = createEvent()
const $store = createStore(0)
$store.watch(foo, (storeValue, eventValue) => {
console.log(`triggered ${storeValue}, ${eventValue}`)
})
foo(1)
// => triggered 0, 1
bar(2)
foo(3)
// => triggered 0, 3
reset(...triggers)
Resets store state to the default value.
A state is reset when Event or Effect is called or another Store is changed.
Formulae
$store.reset(...triggers)
- When any unit from
triggers
list is triggered, update$store
with its default state, fromcreateStore(defaultState)
Arguments
Returns
Store: Current store
Example
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))
// changed 0
// watch method calls its function immediately
increment() // changed 1
increment() // changed 2
reset() // changed 0
reset(triggersArray)
effector 20.15.0
Resets store state to the default value. An overload for arrays of units, which make reset
consistent with merge and store.on(triggers[], fn)
A state is reset when Event or Effect is called or another Store is changed.
Formulae
$store.reset([triggerA, triggerB, ...])
- When any unit from
triggersArray
list is triggered, update$store
with its default state, fromcreateStore(defaultState)
Arguments
Returns
Store: Current store
Example
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))
// changed 0
// watch method calls its function immediately
increment() // changed 1
increment() // changed 2
reset() // changed 0
off(trigger)
$store.off(trigger)
- Removes reducer for given
trigger
, which was installed via \$store.on or \$store.reset - If there was no reducer for that
trigger
, this method will do nothing
Arguments
Returns
Store: Current store
Example
import {createEvent, createStore} from 'effector'
const changedA = createEvent()
const changedB = createEvent()
const $store = createStore(0)
// If you want to unsubscribe from all triggers simultaneously, better to manually merge
const changed = merge([changedA, changedB])
$store.on(changed, (state, params) => state + params)
$store.off(changed)
thru(fn)
since 22.0.0
Call function with the given store and return result as it is.
Formulae
const result = $store.thru(fn)
- Call
fn
with$store
as argument - Return result of the
fn()
call
Arguments
fn
(Function): Function that receivesStore
and returns some value, should be pure
Returns
(any): Value, returned by fn
Example
import {createStore, createEvent} from 'effector'
const enhance = fn => store => store.map(fn)
const inc = createEvent()
const $num = createStore(1)
$num.on(inc, n => n + 1)
//prettier-ignore
const $result = $num
.thru(enhance(x => x + 1))
.thru(enhance(x => x * 10))
$num.watch(n => {
console.log('num', n)
})
// => num 1
$result.watch(n => {
console.log('result', n)
})
// => result 20
inc()
// => num 2
// => result 30
Store Properties
updates
Formulae
$store.updates
- When
$store
is changed triggerupdates
event with the new state
Returns
Event: Event that represents updates of the given store.
Do not manually call this event. It is event that depends on a store.
Use case: watchers, which will not trigger immediately after creation (unlike store.watch)
import {createStore, is} from 'effector'
const $clicksAmount = createStore(0)
is.event($clicksAmount.updates) // => true
$clicksAmount.watch(amount => {
console.log('will be triggered with current state, immediately, sync', amount)
})
$clicksAmount.updates.watch(amount => {
console.log('will not be triggered unless store value is changed', amount)
})
shortName
Returns
(string
): ID or short name of the store
defaultState
Returns
(State
): Default state of the store
Example
const $store = createStore('DEFAULT')
console.log($store.defaultState === 'DEFAULT')
// => true
Utility methods
getState()
Returns current state of store
Returns
(State
): Current state of the store
Example
import {createEvent, createStore} from 'effector'
const add = createEvent()
const $number = createStore(0).on(add, (state, data) => state + data)
$number.watch(n => {
console.log(n)
})
// => 0
add(2)
// => 2
add(3)
// => 5
Derived store
DerivedStore has no specific interface in TypeScript, but it has different implementation in the effector kernel.
Some methods like combine
, .map
, sample
, .pending
returns Store
instance.
The store updates by specific rules defined in the method above. That's why we have different type of stores.
Derived stores are not allowed to be modified from the outside. For example, you shall not add new triggers on the derived store:
const update = createEvent()
const $a = createStore(1)
const $b = createStore(2)
const $derived = combine({a: $a, b: $b})
$derived.on(update, (_, value) => ({a: value, b: value}))
// => .on in derived store is deprecated, use createStore instead
Derived store only allows methods that do not modify state. It means, that DerivedStore cannot be used as target
in sample
:
const update = createEvent()
const $a = createStore(1)
const $b = createStore('foo')
const $derived = combine({a: $a, b: $b})
sample({
clock: update,
fn: value => ({a: value, b: value}),
target: $derived,
})
// => sample: derived unit in "target" is deprecated, use createEvent/createStore instead
These methods are allowed for DerivedStore:
.map
.watch
- using DerivedStore as a
source
and/orclock
insample
and so on - using DerivedStore in
combine
sources
since 23.0.0 banned methods will throw an exception
These methods are banned for DerivedStore:
.on
.reset
- using DerivedStore as a
target
insample
,guard
and so on
Any kind of store can be used as a clock
or source
in methods like sample
.