sample API

import { sample } from "effector";

The sample method is used to connect units. Its main purpose is to take data from one place source and send it to another target when a certain trigger clock occurs.

A common use case is when you need to process an event using data from a store. Instead of using store.getState(), which can lead to inconsistent state, it’s better to use sample.

how to work with sample

How it works

  • When clock triggers, the value from source is read.
  • If a filter is specified and returns true, or if it’s a store with true value, processing continues.
  • If a fn is provided, data is transformed.
  • Data is then passed to the target.

Special behavior of sample

  • If clock is not provided, sample will trigger on every update of source.
  • If target is not provided, sample will create and return a new derived unit.

Returned unit and value

If target is not provided, it will be created at runtime. The type of unit returned depends on this table:

clock \ sourceStoreEventEffect
StoreStoreEventEvent
EventEventEventEvent
EffectEventEventEvent

How to use this table:

  1. Pick the type of clock (column).
  2. Pick the type of source (row).
  3. The intersecting cell shows the return type.

If target is explicitly provided, then that target is returned.

Example:

const event = createEvent();
const $store = createStore();
const $secondStore = createStore();

const $derivedStore = sample({
  clock: $store,
  source: $secondStore,
});
// Returns a derived store because both clock and source are stores

const derivedEvent = sample({
  clock: event,
  source: $store,
});
// Returns a derived event because the clock is an event

Full form

  • Formula
sample({
  clock?, // trigger
  source?, // data source
  filter?, // filter predicate
  fn?, // transformation function
  target?, // target unit
  batch?, // batching flag
  name? // unit name
})

clock

A trigger unit that determines when to sample the source.
Optional.

  • Type
sample({
  clock?: Unit<T> | Unit<T>[],
})

Can be:

  • Event<T> β€” triggers on event call
  • Store<T> β€” triggers on store update
  • Effect<T, Done, Fail> β€” triggers on effect execution
  • Unit<T>[] β€” triggers when any unit in the array is triggered
either clock or source required

Although the clock argument is optional, when using the sample method you must provide either clock or source.

const clicked = createEvent();
const $store = createStore(0);
const fetchFx = createEffect();

sample({
  source: $data,
  clock: clicked,
});

sample({
  source: $data,
  clock: $store,
});

sample({
  source: $data,
  clock: [clicked, fetchFx.done],
});

source

The data source to be read when the clock unit triggers. If clock is not provided, then source is used as the clock. Optional.

  • Type
sample({
  source?: Unit<T> | Unit<T>[] | { [key: string]: Unit<T> },
})

Can be:

  • Store<T> β€” reads the current value of the store
  • Event<T> β€” takes the most recent payload from the event
  • Effect<T, Done, Fail> β€” takes the most recent payload from the effect call
  • Object of units β€” for combining multiple sources
  • Array of units β€” for combining multiple sources
either source or clock required

Although the source argument is optional, when using the sample method you must provide either source or clock.


filter

A predicate function or store used to filter the data. If it returns false (or is a store that holds false), the data will not be passed to target. Optional.

  • Type
sample({
  filter?: Store<boolean> | (source: Source, clock: Clock) => (boolean | Store<boolean>),
})

Can be:

  • Store<boolean> β€” a boolean store (either base or derived)
  • Predicate function β€” returns a boolean value
const $isUserActive = createStore(false);

sample({
  clock: checkScore,
  source: $score,
  filter: (score) => score > 100,
  target: showWinnerFx,
});

sample({
  clock: action,
  source: $user,
  filter: $isUserActive,
  target: adminActionFx,
});

fn

A function used to transform the data before passing it to the target. The function must be pure. Optional.

  • Type
sample({
  fn?: (source: Source, clock: Clock) => Target
})
returned data type

The type of data returned must match the type of data in target.

const $user = createStore<User>({});
const saveUserFx = createEffect((user: User) => {
  // ...
});

sample({
  clock: updateProfile,
  source: $user,
  fn: (user, updates) => ({ ...user, ...updates }),
  target: saveUserFx,
});

sample({
  clock: submit,
  source: $form,
  fn: (form) => form.email,
  target: sendEmailFx,
});

target

The destination unit that will receive the data and be triggered. Optional.

  • Type
sample({
  target?: Unit<T> | Unit<T>[],
})

Can be:

target without target

If target is not specified, sample returns a new derived unit.

const targetEvent = createEvent<string>();
const targetFx = createEffect<string, void>();
const $targetStore = createStore("");

// Event as target
sample({
  source: $store,
  clock: trigger,
  target: targetEvent,
});

// Effect as target
sample({
  source: $store,
  clock: trigger,
  target: targetFx,
});

// Store as target
sample({
  source: $store,
  clock: trigger,
  target: $targetStore,
});

greedy

Deprecated

As of effector 23.0.0, the greedy property is deprecated.

Use batch instead of greedy.


batch

Enables batching of updates for better performance. Default is true. Optional.

  • Type
sample({
  batch?: boolean // Default: true
})

name

The name field allows you to assign a debug-friendly name to the created unit. Optional.

  • Type
sample({
  name?: string
})

Short Form

  • Formula
sample(source, clock, fn?): Unit

This is a shorthand version of the sample method, which always implicitly returns a target.

It supports multiple patterns:

  1. All arguments: sample(source, clock, fn) β€” with a transformation function
  2. Just source and clock: sample(source, clock) β€” no transformation function
  3. source and fn: sample(source, fn) β€” no clock, so source acts as the trigger
  4. One argument: sample(source) β€” only source, which acts as the trigger and the source
  • Return value

The return type depends on the combination of units used and the return type of fn, if present. Otherwise, it falls back to the source.


source

Acts as the data source when the clock triggers. If no clock is provided, source is used as the trigger.

  • Type
sample(source?: Unit<T> | Unit<T>[])

Can be:

  • Store<T> β€” current value of the store
  • Event<T> β€” last triggered payload
  • Effect<T, Done, Fail> β€” last payload sent to the effect
  • Unit<T>[] β€” array of units that triggers when any unit is activated
behavior without clock

If clock is not specified, then source behaves as clock - that is, it acts as the trigger.


clock

The unit that acts as the trigger to read from source. Optional.

  • Type
sample(clock?: Unit<T> | Unit<T>[])

Can be:

  • Event<T> β€” triggered on event call
  • Store<T> β€” triggered on store update
  • Effect<T, Done, Fail> β€” triggered on effect execution
  • Unit<T>[] β€” triggers on any unit in the array
const clicked = createEvent();
const $store = createStore(0);
const fetchFx = createEffect();

sample($data, clicked);

sample($data, $store);

fn

A transformation function to be applied before sending the result to the implicit target. The function must be pure. Optional.

  • Type
sample(fn: (source: Source, clock: Clock) => result)
  • Example
const $userName = createStore("john");

const submitForm = createEvent();

const sampleUnit = sample(
  $userName /* 2 */,
  submitForm /* 1 */,
  (name, password) => ({ name, password }) /* 3 */,
);

submitForm(12345678);

// 1. submitForm is triggered with 12345678
// 2. $userName value is read ("john")
// 3. The values are transformed and passed to sampleUnit

Contributors