Skip to main content

Що робить sample() в Effector?

1. Що таке sample

sample() - це механізм реактивного зв'язування даних між джерелом (source) і «тригером» (clock). Коли відбувається подія (clock), sample «бере» поточне значення (source) і передає його далі - у target або fn.

Тобто sample = «Коли відбулося це, візьми те і зроби те-то».


2. Базовий приклад

javascript
import { createEvent, createStore, sample } from 'effector' const nameChanged = createEvent<string>() const submitClicked = createEvent() const $name = createStore('') $name.on(nameChanged, (_, value) => value) sample({ source: $name, clock: submitClicked, fn: (name) => `Submitting the form with name: ${name}`, target: console.log, }) nameChanged('Alex') submitClicked() // => "Submitting the form with name: Alex"

Пояснення:

  • clock (тригер) = submitClicked
  • source (дані) = $name
  • при кліку submitClicked береться поточне $name
  • fn() створює результат, який іде в target

3. Мнемоніка:

sample = «clock відбувся -> взяти snapshot із source»


4. Параметри sample

javascript
sample({ source, // where we get data from clock, // when we do this fn, // how we transform it filter, // (optional) when it's allowed to pass through target, // where the result goes (event, effect, store) })

Приклад із filter:

javascript
sample({ source: $form, clock: submitClicked, filter: $formValid, target: sendFormFx, })

Відправимо форму (sendFormFx) лише якщо $formValid === true.


5. Приклад зв'язку кількох джерел

source може бути не лише одним store, а об'єктом із кількох сторів:

javascript
sample({ source: { name: $name, email: $email }, clock: submitClicked, fn: ({ name, email }) => ({ name, email }), target: sendFormFx, })

Тепер sample візьме одразу значення обох сторів у момент кліку.


6. Візуально (потік даних)

javascript
[source] ---\ > sample() ---> [target] [clock] ----/
  • source -> звідки беремо дані
  • clock -> що тригерить «взяття семпла»
  • target -> куди йде результат

7. Чому sample кращий за .watch() або .on()

.watch().on()sample()
Реагує на зміну?ЗавждиЗавждиЛише за clock
Контролює момент часуНіНіТак
Дозволяє фільтрувати та зв'язуватиНіНіТак
Використовується для реактивних потоківЧастковоНіОсновний інструмент

Приклад:

javascript
sample({ source: $user, clock: logoutClicked, fn: () => null, target: $user, })

При кліку на logout - обнуляємо $user. .on() тут не підійшов би, адже це не просто зміна стору, а дія за подією.


8. Реальний приклад із застосунку

javascript
const loginClicked = createEvent() const $credentials = createStore({ email: '', password: '' }) const loginFx = createEffect(async (creds) => api.login(creds)) sample({ clock: loginClicked, source: $credentials, filter: $isFormValid, target: loginFx, })

Тепер усе реактивно:

  • при кліку на «Login»
  • якщо форма валідна
  • надсилаємо $credentials у loginFx.

Без зайвого useEffect, if, setState - чиста реактивна логіка.


9. Комбінування sample

Можна викликати sample() ланцюжком - будувати графи залежностей:

javascript
const submitClicked = createEvent() const $data = createStore({ name: 'Alex' }) const saveFx = createEffect(api.saveUser) const saved = sample({ clock: submitClicked, source: $data, target: saveFx }) sample({ clock: saveFx.doneData, fn: () => 'Saved successfully!', target: console.log, })

10. Частий патерн: sample замість "if/await/useEffect"

Філософія Effector:

«Жодних if (formValid) sendForm() - усе описується реактивно через sample і filter».

Це дозволяє писати чисту, детерміновану бізнес-логіку, де порядок дій завжди передбачуваний.


ПІДСУМОК

sample() - це фундамент Effector для реактивних зв'язків: коли відбувається одна подія (clock), бібліотека бере актуальні дані з source, опційно фільтрує/трансформує їх, і надсилає результат у target.


Формула запам'ятовування:

clock відбувся -> «семплюємо» source -> fn() -> target.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.