Skip to main content

Що таке "effect" в Effector?

У Effector effect - це реактивна одиниця для роботи з асинхронними діями (запити, таймери, операції з API тощо). Якщо event - це «щось сталося», а store - «поточний стан», то effect - це "щось виконується" (зазвичай з побічною дією).


1. Що таке effect

Effect - це функція, обгортка над асинхронною логікою, яка автоматично керує станами: pending, done, fail, finally.

Effector робить ефекти реактивними: вони можуть запускатися з подій, оновлювати стори, тригерити нові події і навіть викликати інші ефекти.


2. Приклад базового ефекту

javascript
import { createEffect } from 'effector' const fetchUserFx = createEffect(async (id: number) => { const res = await fetch(`/api/users/${id}`) if (!res.ok) throw new Error('Помилка завантаження') return res.json() }) // Виклик ефекту fetchUserFx(1)

Тут:

  • createEffect() створює реактивний ефект.
  • Всередині - звичайна асинхронна функція.
  • Effector сам відстежує, коли ефект:
    • запущений -> pending = true,
    • завершився -> done,
    • впав з помилкою -> fail.

3. Автоматичні події ефекту

Кожен effect всередині Effector створює 4 вбудовані події:

ПодіяКоли викликаєтьсяКорисно для
.pendingколи ефект виконуєтьсяпоказати "Loading…"
.doneколи ефект завершений успішнооновити дані
.failколи сталася помилкапоказати помилку
.finallyколи ефект завершився (будь-яким результатом)очистити індикатори, логіку завершення

Приклад:

javascript
fetchUserFx.done.watch(({ params, result }) => { console.log('Завантажили користувача', result) }) fetchUserFx.fail.watch(({ error }) => { console.error('Помилка:', error) })

4. Керування станом ефекту

Кожен effect - це не просто функція, а реактивний вузол. У нього є store pending, який можна використовувати в UI:

javascript
import { useUnit } from 'effector-react' function UserLoader() { const [pending, loadUser] = useUnit([fetchUserFx.pending, fetchUserFx]) return ( <button onClick={() => loadUser(1)} disabled={pending}> {pending ? 'Завантаження...' : 'Завантажити користувача'} </button> ) }

Effector сам синхронізує значення pending - без ручного setState.


5. Зв'язок подій і ефектів

Зазвичай ефект запускається через подію, а не напряму:

javascript
import { createEvent, sample } from 'effector' const userRequested = createEvent<number>() sample({ clock: userRequested, target: fetchUserFx, })

Тепер userRequested(42) викличе fetchUserFx(42).


6. Обробка результату через store

Після виконання ефекту дані можна зберегти в store:

javascript
import { createStore } from 'effector' const $user = createStore(null) .on(fetchUserFx.doneData, (_, user) => user) .reset(fetchUserFx.fail) $user.watch(console.log)

.doneData - це шорткат для effect.done.map(({ result }) => result).


7. Реактивний ланцюжок "event → effect → store → UI"

javascript
[event: userRequested][effect: fetchUserFx][store: $user][UI]

Це класичний dataflow Effector: користувач ініціює подію -> ефект виконує запит -> результат реактивно оновлює стор -> UI оновлюється автоматично.


8. Відмінність від event і store

eventeffectstore
ПризначенняПовідомити, що щось сталосяВиконати асинхронну або побічну операціюЗберігати й оновлювати дані
Повертає значенняНіПромісДані (через .getState())
Може змінювати stateЛише через зв'язку зі storeЛише через .doneData/.failDataТак
РеактивністьТакТакТак

9. Приклад повного сценарію

javascript
import { createEvent, createEffect, createStore, sample } from 'effector' // 1. подія від UI const userRequested = createEvent<number>() // 2. асинхронний ефект const fetchUserFx = createEffect(async (id: number) => { const res = await fetch(`/api/users/${id}`) return res.json() }) // 3. store для даних const $user = createStore(null).on(fetchUserFx.doneData, (_, user) => user) // 4. пов'язуємо подію з ефектом sample({ clock: userRequested, target: fetchUserFx, }) // 5. слухаємо результат $user.watch(console.log) // виклик userRequested(10)

Підсумок

Effect в Effector - це реактивна асинхронна операція. Він:

  • виконує побічні дії (запити, таймери, API),
  • керує станом завантаження і помилок,
  • пов'язується з іншими сутностями (events, stores),
  • і ідеально інтегрується з реактивним потоком даних.

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

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

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