Glossary
This is a glossary of the core terms in Effector, along with their type signatures. The types are documented using TypeScript notation.
Event
Event is a function you can subscribe to. It can be intention to change store, fact about what happening in application, command to be executed, aggregated analytics trigger and so on.
function createEvent<E>(eventName?: string): Event<E>
createEvent(eventName)
creates event
type Event<Payload> = { (payload: Payload): Payload watch(watcher: (payload: Payload) => any): Subscription map<T>(fn: (payload: Payload) => T): Event<T> filter(options: {fn(payload: Payload): boolean}): Event<Payload> filterMap<T>(fn: (payload: Payload) => T | void): Event<T> prepend<Before>(fn: (params: Before) => Payload): Event<Before> shortName: string}
(payload)
callsEvent
with payloadwatch(watcher)
listens to this event and calls givenwatcher
map(fn)
filter({fn})
creates new event that will receive update only when givenfn
returns truefilterMap(fn)
creates new event that will receive value, returned by givenfn
, but only when it returns anything but undefined. Use cases: extract value from react's refs; statically typed filters;prepend(fn)
creates new event that preprocesses payload before calling original eventshortName
is used for debug
Effect
Effect is a container for async function.
It can be safely used in place of the original async function.
It returns promise with result of function call
The only requirement for function:
- Should have zero or one argument
function createEffect<Params, Done, Fail>( effectName?: string,): Effect<Params, Done, Fail>
createEffect(effectName)
creates effect
type Effect<Params, Done, Fail = Error> = { (payload: Params): Promise<Done> done: Event<{params: Params; result: Done}> fail: Event<{params: Params; error: Fail}> use: { (asyncFunction: (params: Params) => Promise<Done>): this getCurrent(): (params: Params) => Promise<Done> } watch(watcher: (payload: Params) => any): Subscription prepend<Before>(fn: (_: Before) => Params): Event<Before> shortName: string}
(payload)
callsEffect
with payloaduse(asyncFunction)
injects async function into effect (can be called multiple times)watch(watcher)
listens to this effect and calls givenwatcher
prepend(fn)
creates new effect that preprocesses payload before calling original eventshortName
is used for debug
Store
Store is an object that holds the state tree. There can be multiple stores.
function createStore<State>(defaultState: State): Store<State>
function createStoreObject<State: {[key: string]: Store<any> | any}>( obj: State): Store<$ObjMap<State, <S>(field: Store<S> | S) => S>>
createStore(defaultState)
creates new storecreateStoreObject(obj)
combines multiple stores into one
type Store<State> = { reset( ...triggers: Array<Event<any> | Effect<any, any, any> | Store<any>> ): this getState(): State map<T>(fn: (_: State) => T): Store<T> on<E>( trigger: Event<E> | Effect<E, any, any> | Store<E>, handler: (state: State, payload: E) => State | void, ): this off(trigger: Event<any> | Effect<any, any, any> | Store<any>): void watch<E>( watcher: (state: State, payload: E, type: string) => any, ): Subscription watch<E>( trigger: Event<E> | Effect<E, any, any> | Store<E>, watcher: (state: State, payload: E) => any, ): Subscription thru<U>(fn: (store: Store<State>) => U): U shortName: string defaultState: State updates: Event<State>}
reset(...triggers)
resets state to default when event occursgetState()
returns current statemap(fn)
creates computed store from previous stateon(event, handler)
callsreducer
on store when event occursoff(event)
disablesreducer
watch(watcher)
calls givenwatcher
when event occursthru(fn)
calls function with this store and return its resultshortName
is used for debugdefaultState
iscreateStore
first argumentupdates
isevent
for watchstore
changes only
Domain
Domain is a namespace for your events, stores and effects.
Domain can subscribe to event, effect, store or nested domain creation with onCreateEvent
, onCreateStore
, onCreateEffect
, onCreateDomain
methods.
It is useful for logging or other side effects.
function createDomain(domainName?: string): Domain
createDomain(domainName)
creates new domain
type Domain = { onCreateEvent(hook: (newEvent: Event<unknown>) => any): Subscription onCreateEffect( hook: (newEffect: Effect<unknown, unknown, unknown>) => any, ): Subscription onCreateStore(hook: (newStore: Store<unknown>) => any): Subscription onCreateDomain(hook: (newDomain: Domain) => any): Subscription event<Payload>(name?: string): Event<Payload> effect<Params, Done, Fail>(name?: string): Effect<Params, Done, Fail> store<State>(defaultState: State): Store<State> domain(name?: string): Domain}
onCreateEvent(hook)
calls hook when nestedEvent
createdonCreateEffect(hook)
calls hook when nestedEffect
createdonCreateStore(hook)
calls hook when nestedStore
createdonCreateDomain(hook)
calls hook when nestedDomain
createdevent(name)
is the function that createsEvent
described above.effect(name)
is the function that createsEffect
described above.store(defaultState)
is the function that creates Store described above.domain(name)
creates nested domain.
Reducer
type StoreReducer<State, E> = (state: S, payload: E) => State | voidtype EventOrEffectReducer<T, E> = (state: T, payload: E) => T
Reducer calculates a new state given the previous state and an event.
Watcher
type Watcher<T> = (update: T) => any
Watcher is used for side effects
Subscription
type Subscription = { (): void unsubscribe(): void}
Pureness
Most of functions in api shouldn't call other events or effects: it's easier to reason about application dataflow when imperative triggers are grouped inside watchers and effect handlers rather than speaded across entire business logic
Correct, imperative:
import {createStore, createEvent} from 'effector'
const login = createStore('guest')
const loginSize = login.map(login => login.length)
const submitLoginSize = createEvent()
loginSize.watch(size => { submitLoginSize(size)})
store.map in docs store.watch in docs
Correct, declarative:
import {createStore, createEvent, forward} from 'effector'
const login = createStore('guest')
const loginSize = login.map(login => login.length)
const submitLoginSize = createEvent()
forward({ from: loginSize, to: submitLoginSize,})
Incorrect:
import {createStore, createEvent, forward} from 'effector'
const submitLoginSize = createEvent()
const login = createStore('guest')const loginSize = login.map(login => { // no! use forward or watch instead submitLoginSize(login.length) return login.length})