Event
Event is an intention to change the state. Let's imagine life situation, you enter a shop and, according to etiquette, you have to say "hello" - intention, then you say "hello" - event.
Event calls always return its payload:
import {createEvent} from 'effector'
const event = createEvent()
console.log(event(1))// => 1console.log(event())// => undefinedEvent Methods
watch(watcher)
It is a function which allows you to watch the event or to create side-effects.
Formulae
const unwatch = event.watch(fn)- Call
fnon eacheventtrigger, pass payload ofeventas argument tofn - When
unwatchis called, stop callingfnon eacheventtrigger
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 happenedmap(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
firstis triggered, pass payload fromfirsttofn - Trigger
secondwith 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] nowfilter({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 a particular size of the sneakers model, and in addition, you want to receive a notification if they have it, and ignore any other notification. Therefore filtering can be helpful for that. Event filtering works in the same way. If filter returns true, the event will be called.
Formulae
const second = first.filter({fn})- When
firstis triggered, pass payload fromfirsttofn - If
fn()returnstrue,secondwill 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 triggeredfilterMap(fn)
Creates a new event, which will be called after the original event is called if fn returns a value other than undefined.
Imagine a situation, you come up to a grocery store and you have let's say a task: you need to buy 10 apples, but only those that are red, otherwise nothing.
Let's consider by steps:
- Take one apple;
- Have a look, is it red(put in a pack) or not(take another).
And you repeat this until you complete the task. Now think about it in the Effector terms 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
firstis triggered, callfnwith payload fromfirst- If
fn()returnedundefineddo not triggersecond - If
fn()returned some data, triggersecondwith 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 sends transformed data into the source event. Works kind of like reverse .map. In 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
secondevent is triggered - Call
fnwith payload fromsecond - Trigger
firstwith 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
Effector