Event
Event is an intention to change state. Let's imagine life situation, you come to a shop and on etiquette you should say "hello" - intention, then you say "hello" - event.
Event calls always returns its payload:
import {createEvent} from 'effector'
const event = createEvent()
console.log(event(1))// => 1console.log(event())// => undefined
Event Methods
watch(watcher)
It is a function which allows you to follow the event or to create side-effects.
Formulae
const unwatch = event.watch(fn)
- Call
fn
on eachevent
trigger, pass payload ofevent
as argument tofn
- When
unwatch
is called, stop callingfn
on eachevent
trigger
Arguments
watcher
(Watcher): A function that receivespayload
.
Returns
Subscription: Unsubscribe function.
Example
import {createEvent} from 'effector'
const sayHi = createEvent()const unwatch = sayHi.watch(name => console.log(`${name}, hi there!`))
sayHi('Peter') // => Peter, hi there!unwatch()
sayHi('Drew') // => nothing happened
map(fn)
Creates a new event, which will be called after the original event is called, applying the result of a fn
as a payload. It is special function which allows you to decompose dataflow, extract or transform data.
Formulae
const second = first.map(fn)
- When
first
is triggered, pass payload fromfirst
tofn
- Trigger
second
with the result of thefn()
call as payload
Arguments
fn
(Function): A function that receivespayload
, should be pure.
Returns
Event: New event.
Example
import {createEvent} from 'effector'
const userUpdated = createEvent()const userNameUpdated = userUpdated.map(({name}) => name) // you may decompose dataflow with .map() methodconst userRoleUpdated = userUpdated.map(({role}) => role.toUpperCase()) // either way you can transform data
userNameUpdated.watch(name => console.log(`User's name is [${name}] now`))userRoleUpdated.watch(role => console.log(`User's role is [${role}] now`))
userUpdated({name: 'john', role: 'admin'})// => User's name is [john] now// => User's role is [ADMIN] now
filter({fn})
Creates a new event, which will be called after the original event is called if fn
returns true
.
Let's assume a standard situation when you want to buy sneakers in the shop, but there is no size. You subscribe to the concrete size of the sneakers model, besides you want to receive a notification if there will have and don't receive others. Therefore filtering is needed for that. Event filtering works the same. If the filter returns true
, the event will be called.
Formulae
const second = first.filter({fn})
- When
first
is triggered, pass payload fromfirst
tofn
- If
fn()
returnstrue
,second
will be triggered with payload fromfirst
Arguments
fn
(Function): A function that receivespayload
, should be pure.
Returns
Event: New event.
Example
import {createEvent, createStore} from 'effector'
const numbers = createEvent('event with {x: number}')
const positiveNumbers = numbers.filter({ fn: ({x}) => x > 0,})
const lastPositive = createStore(0).on(positiveNumbers, (n, {x}) => x)
numbers({x: 0}) // store won't triggerednumbers({x: -10}) // store won't triggerednumbers({x: 10}) // store will triggered
filterMap(fn)
Creates a new event, which will be called after the original event is called if fn
returns a value other than undefined.\
Imagine you come to the product shop and you have let's say a task: you should buy 10 apples, but only red otherwise nothing.
Let's consider by steps:
- Take one apple;
- Have a look red(put in a pack) or no(take another).
And you repeat this till no complete a task. Now think about it in Effector context and we consider the positive case:
- Take an apple - event;
- Have a look red or no - filter;
- You keep it - map;
- Put in pack - event.
- Pack - store
You may see that we united filter()
and map()
methods, the reason for creating was an impossibility to event filtering.
Formulae
const second = first.filterMap(fn)
- When
first
is triggered, callfn
with payload fromfirst
- If
fn()
returnedundefined
do not triggersecond
- If
fn()
returned some data, triggersecond
with data fromfn()
- If
Arguments
fn
(Function): A function that receivespayload
, should be pure.
Returns
Event: New event.
Example
import React from 'react'import ReactDOM from 'react-dom'import {createEvent, createStore} from 'effector'
const openModal = createEvent('open that modal')const closeModal = createEvent('close that modal')
const openModalUnboxed = openModal.filterMap(ref => { if (ref.current) return ref.current})
openModalUnboxed.watch(modal => modal.showModal())
closeModal .filter({ fn: ref => { if (ref.current) return ref.current }, }) .watch(modal => modal.close())
const modalRef = React.createRef()
const App = () => ( <> <dialog ref={modalRef}> <form method="dialog"> <fieldset> <legend>Modal</legend> Tap to close <button type="submit" onSubmit={() => closeModal(modalRef)}> ❌ </button> </fieldset> </form> </dialog>
<button onClick={() => openModal(modalRef)}>Open modal</button> </>)
ReactDOM.render(<App />, document.getElementById('root'))
prepend(fn)
Creates an event, upon trigger it does send transformed data into source event. Works kind of like reverse .map
. In the case of .prepend
data transforms before the original event occurs and in the case of .map
, data transforms after original event occurred.
Formulae
const second = first.prepend(fn)
- When
second
event is triggered - Call
fn
with payload fromsecond
- Trigger
first
with result offn()
Arguments
fn
(Function): A function that receivespayload
, should be pure.
Returns
Event: New event.
Example
import {createEvent} from 'effector'
const nameChanged = createEvent()nameChanged.watch(name => console.log(`Current name is: ${name}`))
const inputChanged = nameChanged.prepend(e => e.target.value) // event, which will be bound to DOM elementconst input = document.createElement('input')input.onchange = inputChanged
document.body.appendChild(input)// input something in input, and press Enter// => Current name is: something