sample(sourceStore, clockEvent, fn)
Overall this method can be used in order to link two nodes, resulting the third one, which will fire only upon clock
node trigger.
Passes current sourceStore
's state and clockEvent
's value to fn
handler. Quite a common case when you need to handle some event with some store's state. Instead of using store.getState()
, in body of effect, which may cause race conditions and inconsistency of state at the moment of effect's handler invocation, it is more appropriate to use sample
method as described below.
Returned Unit may be observed (via watch
), since it's valid graph node.
Arguments
sourceStore
(Store): Source eventclockEvent
(Event): Clock(Trigger) eventfn
? ((source, clock) => result): Optional combinator function, should be pure. Since, this handler is supposed to organize data flow, you should avoid declaring side-effects here. It's more appropriate to place it inwatch
method for sampled node;
Returns
(Event
) - Event, which fires upon clock is triggered
Example 1
import {createStore, createEvent, sample} from "effector";
const store = createStore('hello zerobias');
const event = createEvent();
const sampled = sample(store, event);
sampled.watch(console.log);
event() // => hello zerobias
Example 2
import {createStore, createEvent, sample} from "effector"
const login = createStore('peter')
const sendMessage = createEvent()
const fullMessage = sample(
login,
sendMessage,
(login, text) => ({login, text}),
)
fullMessage.watch(({login, text}) => {
console.log(`[${login}]: ${text}`)
})
sendMessage('hello')
// => [peter]: hello
sendMessage('how r u?')
// => [peter]: how r u?
sample(sourceEvent, clockEvent, fn)
Passes last sourceEvent
invocation argument value and clockEvent
value to fn
handler.
Arguments
sourceEvent
(Event): Source eventclockEvent
(Event): Clock(Trigger) eventfn
? ((source, clock) => result): Optional combinator function, should be pure
Returns
(Event
) - Event, which fires upon clock is triggered
Example
import {createEvent, sample} from "effector"
const event1 = createEvent();
const event2 = createEvent();
const sampled = sample(event1, event2, (a, b) => `${a} ${b}`);
sampled.watch(console.log);
event1("Hello");
event2("World"); // => Hello World
event2("effector!"); // => Hello effector!
sampled("Can be invoked too!"); // => Can be invoked too!
sample(event, store, fn)
Passes last event
invocation argument value and store
's updated state to fn
handler.
Arguments
event
(Event): Source eventstore
(Store): Triggers sampled unit upon store updatefn
? ((source, clock) => result): Optional combinator function, should be pure
Returns
(Event
) - Event, which fires upon clock is triggered
Example
import {createEvent, createStore, sample} from "effector"
const event = createEvent();
const inc = createEvent();
const count = createStore(0)
.on(inc, (state) => state + 1);
const sampled = sample(event, count, (c, i) => `Current count is ${i}, last event invocation: ${c}`);
sampled.watch(console.log);
inc() // => nothing
event("foo");
inc() // => Current count is 2, last event invocation: foo
event("bar");
inc(); // => Current count is 3, last event invocation: bar
sample(sourceStore, clockStore, fn)
Passes last sourceStore
's current state and clockStore
's updated state to fn
handler, upon clockStore
's update.
Arguments
sourceStore
(Store): Source storeclockStore
(Store): Triggers sampled unit upon store updatefn
? ((source, clock) => result): Optional combinator function, should be pure
Returns
(Store
) - Store, which updates upon clock update
Example
import {createEvent, createStore, sample} from "effector";
const inc = createEvent();
const setName = createEvent();
const name = createStore("John")
.on(setName, (_, v) => v);
const clock = createStore(0)
.on(inc, (i) => i + 1);
const sampled = sample(name, clock, (name, i) => `${name} has ${i} coins`);
sampled.watch(console.log);
// => John has 0 coins (initial store update triggered sampled store)
setName("Doe");
inc(); // => Doe has 1 coins
sample({source, clock, fn, greedy?})
Object-like arguments passing, working exactly the same as examples above do.
greedy
modifier defines, whether sampler will wait of resolving calculation result, and will batch all updates, resulting only one trigger, either will be triggered upon every linked node invocation, e.g. if greedy
is true
, sampler
will fire, upon trigger of every node, linked to clock, whereas non-greedy sampler(greedy: false)
will fire upon the last linked node trigger.
Arguments
params
(Object): Configuration object
Returns
(Event
|Store
) - Unit, which fires/updates upon clock
is trigged
Example
import {createEvent, createStore, sample} from "effector"
const clickButton = createEvent()
const closeModal = clickButton.map(() => 'close modal')
const lastEvent = createStore(null)
.on(clickButton, (_, data) => data)
.on(closeModal, () => 'modal')
lastEvent.updates.watch(data => {
// here we need everything
//console.log(`sending important analytics event: ${data}`)
})
lastEvent.updates.watch(data => {
//here we need only final value
//console.log(`render <div class="yourstatus">${data}</div>`)
})
const analyticReportsEnabled = createStore(false)
const commonSampling = sample({
source: analyticReportsEnabled,
clock: merge([clickButton, closeModal]),
fn: (isEnabled, data) => ({isEnabled, data}),
})
const greedySampling = sample({
source: analyticReportsEnabled,
clock: merge([clickButton, closeModal]),
fn: (isEnabled, data) => ({isEnabled, data}),
greedy: true,
})
commonSampling.watch(data => console.log('non greedy update', data))
greedySampling.watch(data => console.log('greedy update', data))
clickButton('click A')
clickButton('click B')