Store
Store is an object that holds the state value. There can be multiple stores.
Store Methods
map(fn: (state: State, lastState?: T) => T)
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
$firststore is updated, callfnwith new state and previous state - Next update
$secondstore with result offn()call and trigger all subscribers
Arguments
fn(Function): Function that receivesstateandlastState?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
Store: New 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 11on(trigger, handler)
Updates state when trigger is triggered by using handler. For each trigger, last installed handler will override previous handlers (useful for dynamic behavior).
Formulae
$store.on(trigger, handler)- When
triggeris triggered, callhandlerwith payload of thetriggerand data of$store - Next update
$storewith result ofhandler()call and trigger all subscribers
Arguments
triggerEvent, Effect or Storehandler(Function): Reducer function that receivesstateandparamsand returns a new state, should be pure. A store cannot hold anundefinedvalue. 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, (state, params) => state + params)
store.watch(value => { console.log('updated', value)})
changed(2)// => updated 2
changed(2)// => updated 4on(triggers[], handler)
Updates state when any from triggers is triggered by using handler.
Formulae
$store.on([triggerA, triggerB, ...], handler)- When
triggerAortriggerBis triggered, callhandlerwith payload of thetriggerAortriggerBand data of$store - Next update
$storewith result ofhandler()call and trigger all subscribers - Any count of triggers can be passed to
triggers
Arguments
triggersarray of Event, Effect or Storehandler(Function): Reducer function that receivesstateandparamsand returns a new state, should be pure. A store cannot hold anundefinedvalue. 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 store = createStore(0)const changedA = createEvent()const changedB = createEvent()
store.on([changedA, changedB], (state, params) => state + params)
store.watch(value => { console.log('updated', value)})
changedA(2)// => updated 2
changedB(2)// => updated 4
// You can unsubscribe from any triggerstore.off(changedA)Unsubscribe example
import {createEvent, createStore} from 'effector'
const store = createStore(0)const changedA = createEvent()const changedB = createEvent()
// If you want to unsubscribe from all triggers simultaneously, better to manually mergeconst changed = merge([changedA, changedB])
store.on(changed, (state, params) => state + params)
store.off(changed)watch(watcher)
Call watcher function each time when store is updated.
If trigger not passed, run watcher on each event that linked to the store.
Formulae
const unwatch = $store.watch(watcher)- On initialize and each
$storeupdate, callwatcherwith the new state of$store - When
unwatchis 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: 0add(4)// => current value: 4add(3)// => current value: 7watch(trigger, watcher)
Run watcher only when trigger event triggered.
Formulae
const unwatch = $store.watch(trigger, watcher)- On each
$storeupdate with passedtrigger, callwatcherwith the new state of$storeand payload fromtrigger - When
unwatchis called, stop callingwatcher
Arguments
triggerEvent, Effect or Store: Trigger, which leads to call ofwatcherwatcher(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, 3Example 2
Here .on(bar, ...) changes the state between foo executions.
But .watch reacts only to foo event
import {createEvent, createStore} from 'effector'
const foo = createEvent()const bar = createEvent()
const store = createStore(0).on(bar, (state, value) => value)
store.watch(foo, value => { console.log(`triggered ${value}`)})
foo(1)// => triggered 0
bar(2)
foo(3)// => triggered 2Example 3
Here watch reacts only to incr and decr events, because it is explicitly used in .on calls. But doesn't react to any other event.
import {createEvent, createStore} from 'effector'
const incr = createEvent()const decr = createEvent()const another = createEvent()
const store = createStore(0) .on(incr, (state, value) => state + value) .on(decr, (state, value) => state - value)
store.watch(value => console.log(`triggered ${value}`))
another(100)incr(1) // 0 + 1 = 1incr(2) // 1 + 2 = 3decr(3) // 3 - 3 = 0another(200)Example with Effect
Effect is an Event with 2 additional events: fail and done.
You can subscribe to fail and done events of the effect.
import {createEffect, createStore} from 'effector'
const effectFx = createEffect().use( value => new Promise(res => setTimeout(res, 200, value)),)
const store = createStore('initial')
store.watch(effectFx, (state, params) => console.log(`executed with ${params}`))
store.watch(effectFx.done, (state, {params, result}) => console.log(`executed with ${params}, resolved with ${result}`),)
store.watch(effectFx.fail, (state, {params, result}) => console.log(`rejected with ${params}, resolved with ${result}`),)
effectFx(100)Example with another Store
One store can subscribe to updates of another store.
import {createEvent, createStore} from 'effector'
const change = createEvent()
const first = createStore(0).on(change, (state, value) => state + value)
const second = createStore(100)
second.watch(first, (secondState, firstState) => console.log(secondState * firstState),)
// Change first store and trigger watch in secondchange(20)Output
> 0> 2000Example with watcher
import {createEvent, createStore} from 'effector'
const foo = createEvent()
const store = createStore(0)
store.watch(foo, (storeValue, eventValue) => { console.log(`store: ${storeValue}, event: ${eventValue}`)})
foo(1)Output
> store: 0, event: 1reset(...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
triggerslist is triggered, update$storewith its default state, fromcreateStore(defaultState)
Arguments
Returns
Store: Current store
Example
import {createEvent, createStore} from 'effector'
const store = createStore(0)const increment = createEvent()const reset = createEvent()
store.on(increment, state => state + 1).reset(reset)
store.watch(state => console.log('changed', state))// changed 0// watch method calls its function immediately
increment() // changed 1increment() // changed 2reset() // changed 0off(trigger)
$store.off(trigger)- Removes handler for given
trigger, which was installed via $store.on - If there was no handler for that
trigger, this method will do nothing
Arguments
Returns
Store: Current store
getState()
Returns current state of store
Returns
(State): Current state of the store
Example
import {createEvent, createStore} from 'effector'
const store = createStore(0)const updated = createEvent()
store.on(updated, (state, value) => state + value)
updated(2)updated(3)
store.watch(console.log) // => 5thru(fn)
Creates a new store. This method calls a function that receives Store. Other words it's an "escape hatch" for creating composed functions, and also making chains.
For example, you want to make multiple, summary and divide operations. You can create these functions and use them in .thru.
Formulae
const $new = $store.thru(fn)- Call
fnwith$storeas argument - Set result of the
fn()call to$new
Arguments
fn(Function): Function that receivesStoreand returns some value
Returns
(any): Value, returned by fn
Example
import {createStore} from 'effector'
const sum = value => value + 10const square = value => value * valueconst divide = value => value / 2
const enhance = fn => store => store.map(fn)
const store = createStore(0)const newStore = store .thru(enhance(sum)) .thru(enhance(square)) .thru(enhance(divide)) .watch(state => console.log(`newStore: ${state}`))Output
// sum: 10// square: 100// divide: 50
> newStore: 50Store Properties
updates
Formulae
$store.updates- When
$storeis changed triggerupdatesevent with the new state
Returns
Event: Event that represents updates of the given 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
Effector