sample
API
import { sample } from "effector";
Метод для связывания юнитов. Его главная задача - брать данные из одного места source
и передавать их в другое место target
при срабатывании определённого триггера clock
.
Типичный вариант использования – когда необходимо обработать какое-либо событие используя данные из стора. Вместо использования store.getState()
, которое может вызвать несогласованность состояния, лучше использовать метод sample
.
Узнайте как композировать юниты и работать с методом sample
Алгоритм работы
- При срабатывании
clock
прочитать значение изsource
- Если указан
filter
, и результат функции вернулtrue
или стор со значениемtrue
, то продолжить - Если указан
fn
, то преобразовать данные - И передать данные в
target
.
Особенности работы sample
- Если
clock
не передан,sample
будет срабатывать при каждом обновленииsource
. - Если
target
не передан, тоsample
создаст и вернёт новый производный юнит
Возвращаемый юнит и значение
Если target
не передан, то он будет создан при вызове. Тип создаваемого юнита описан в данной таблице:
clock \ source | Store | Event | Effect |
---|---|---|---|
Store | Store | Event | Event |
Event | Event | Event | Event |
Effect | Event | Event | Event |
Использование таблицы:
- Выбираем тип источника
clock
, это столбец - Тип
source
– это строка - Устанавливаем соответствие между столбцом и строкой
В случае, если target
передан явно, то возвращаемым значением будет тот же самый target
.
Например:
const event = createEvent();
const $store = createStore();
const $secondStore = createStore();
const $derivedStore = sample({
clock: $store,
source: $secondStore,
});
// Результатом будет производный стор,
// так как `source` и `clock` являются сторами
const derivedEvent = sample({
clock: event,
source: $store,
});
// Результатом будет производное событие, так как `clock` – событие
Полная форма
- Формула
sample({
clock?, // триггер
source?, // источник данных
filter?, // фильтр
fn?, // функция-трансформатор
target?, // целевой юнит
batch?, // флаг батчинга
name? // имя sample юнита
})
clock
Аргумент clock
является триггером, определяющий момент взятия данных из source
.
Является опциональным.
- Тип
sample({
clock?: Unit<T> | Unit<T>[],
})
Может иметь сигнатуру:
Event<T>
- срабатывает при вызове событияStore<T>
- срабатывает при изменении стораEffect<T, Done, Fail>
- срабатывает при вызове эффектаUnit<T>[]
- массив юнитов срабатывает при активации любого из них
Хотя аргумент clock
является опциональным, при использовании метода sample
необходимо указать либо clock
, либо source
.
const clicked = createEvent();
const $store = createStore(0);
const fetchFx = createEffect();
// Event как clock
sample({
source: $data,
clock: clicked,
});
// Store как clock
sample({
source: $data,
clock: $store,
});
// Массив как clock
sample({
source: $data,
clock: [clicked, fetchFx.done],
});
source
Является источником данных, откуда берутся данные при срабатывании clock
. Если clock
не указан, тогда source
используется как clock
.
Является опциональным.
- Тип
sample({
source?: Unit<T> | Unit<T>[] | {[key: string]: Unit<T>},
})
Может иметь сигнатуру:
Store<T>
- данные берутся из текущего значения стораEvent<T>
- возьмется последнее значение, с которым запускалось событиеEffect<T, Done, Fail>
- возьмется последнее значение, с которым запускался эффект- Объект с юнитами - для комбинирования нескольких источников
- Массив с юнитами - для комбинирования нескольких источников
Хотя аргумент source
является опциональным, при использовании метода sample
необходимо указать либо source
, либо clock
.
filter
Функция-предикат для фильтрации. Если возвращает false
или стор со значением false
, данные не будут переданы в target
.
Является опциональным.
- Тип
sample({
filter?: Store<boolean> | (source: Source, clock: Clock) => (boolean | Store<boolean>),
})
Может иметь сигнатуру:
Store<boolean>
– стор сboolean
значением, как производный так и базовый- Функция-предикат – функция возвращающая
boolean
значение
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
Функция для трансформации данных перед передачей в target
. Функция должна быть чистой.
Является опциональным.
- Тип
sample({
fn?: (source: Source, clock: Clock) => Target
})
Тип возвращаемых данных должен совпадать с типом данных в 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
Целевой юнит, который получит данные и будет вызван.
Является опциональным.
- Тип
sample({
target?: Unit<T> | Unit<T>[],
})
Может иметь сигнатуру:
EventCallable<T>
- событие (не производное) будет вызвано с даннымиEffect<T, Done, Fail>
- эффект будет вызван с даннымиStoreWritable<T>
- стор (не производный) будет обновлён данными- Массив с юнитами - будет вызван каждый юнит в массиве
Если target
не указан, sample
возвращает новый производный юнит.
const targetEvent = createEvent<string>();
const targetFx = createEffect<string, void>();
const $targetStore = createStore("");
// Event как target
sample({
source: $store,
clock: trigger,
target: targetEvent,
});
// Effect как target
sample({
source: $store,
clock: trigger,
target: targetFx,
});
// Store как target
sample({
source: $store,
clock: trigger,
target: $targetStore,
});
greedy
Начиная с effector 23.0.0 свойство greedy
устарело.
Используйте batch
вместо greedy
.
batch
Группирует обновления для лучшей производительности. По умолчанию true
.
Является опциональным.
- Тип
sample({
batch?: boolean // По умолчанию true
})
name
Свойство name
позволяет задать имя создаваемому юниту. Это имя используется для отладки.
Является опциональным.
- Тип
sample({
name?: string
})
Краткая форма
- Формула
sample(source, clock, fn?): Unit
Альтернативная запись метода, всегда имеет неявный target
.
Краткая форма также имеет несколько паттернов написания:
- Все аргументы:
sample(source, clock, fn)
- с функцией-трансформером source
иclock
:sample(source, clock)
- без функции-трансформераsource
иfn
:sample(source, fn)
- с функцией-трансформером, но безclock
, тогдаsource
ведет какclock
- Один аргумент:
sample(source)
- толькоsource
, тогдаsource
ведет какclock
- Возвращаемое значение
Возвращаемое значение зависит от переданных юнитов, а тип данных от fn
, если присутствует, иначе от source
.
source
Является источником данных, откуда берутся данные при срабатывании clock
. Если clock
не указан, тогда source
используется как clock
.
- Тип
sample(source?: Unit<T> | Unit<T>[])
Может иметь сигнатуру:
Store<T>
- данные берутся из текущего значения стораEvent<T>
- возьмется последнее значение, с которым запускалось событиеEffect<T, Done, Fail>
- возьмется последнее значение, с которым запускался эффектUnit<T>[]
- массив юнитов срабатывает при активации любого из них
Если clock
не указан, тогда source
ведет себя как clock
- то есть является триггером.
clock
Аргумент clock
является триггером, определяющий момент взятия данных из source
.
Является опциональным.
- Тип
sample(clock?: Unit<T> | Unit<T>[])
Может иметь сигнатуру:
Event<T>
- срабатывает при вызове событияStore<T>
- срабатывает при изменении стораEffect<T, Done, Fail>
- срабатывает при вызове эффектаUnit<T>[]
- массив юнитов срабатывает при активации любого из них
const clicked = createEvent();
const $store = createStore(0);
const fetchFx = createEffect();
sample($data, clicked);
sample($data, $store);
fn
Функция для трансформации данных перед передачей в target
. Функция должна быть чистой.
Является опциональным.
- Тип
sample(fn: (source: Source, clock: Clock) => result)
- Пример
const $userName = createStore("john");
const submitForm = createEvent();
const sampleUnit = sample(
$userName /* 2 */,
submitForm /* 1 */,
(name, password) => ({ name, password }) /* 3 */,
);
submitForm(12345678);
// 1. при вызове submitForm с аргументом 12345678
// 2. прочитать значение из стора $userName ('john')
// 3. преобразовать значение из submitForm (1) и $userName (2) и вызвать sampleUnit
Связанные API и статьи
- API
- Статьи
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.