Що таке "domain"?
У Effector domain - це контейнер, який об'єднує пов'язані між собою частини логіки:
store, event, effect, sample тощо.
Якщо говорити просто:
Domain - це «область відповідальності» (feature-модуль), всередині якої живуть усі пов'язані стани, події та ефекти.
1. Що таке Domain концептуально
Effector - реактивна система, де можна створювати багато подій і сторів. Коли проєкт зростає, їх стає сотні, і потрібно впорядкувати все це.
Тут і допомагає Domain: він створює ієрархію, інкапсуляцію і єдину точку керування для модуля.
2. Приклад найпростішого Domain
import { createDomain } from 'effector'
// створюємо domain
const userDomain = createDomain('user')
// створюємо події, стори і ефекти всередині нього
const fetchUserFx = userDomain.createEffect(async (id: number) => {
const res = await fetch(`/api/users/${id}`)
return res.json()
})
const userLoaded = userDomain.createEvent()
const $user = userDomain.createStore(null)
.on(fetchUserFx.doneData, (_, user) => user)
.on(userLoaded, (_, user) => user)Тепер усе, що стосується користувача, живе в одному domain-і:
- ефекти,
- події,
- стори.
3. Навіщо потрібен Domain
| Мета | Опис |
|---|---|
| Групування логіки | Можна зберігати все, що стосується однієї feature, в одній області. |
| Керування життєвим циклом | Domain можна скинути, очистити або клонувати цілком. |
| Обробка помилок і логування | Domain вміє перехоплювати помилки всіх своїх ефектів. |
| SSR і ізоляція | Можна створювати окремі екземпляри доменів для кожного запиту користувача (уникаючи конфліктів стану). |
4. Обробка помилок всередині Domain
У Domain є вбудовані хуки, наприклад .onCreateEffect, .onCreateStore, .onCreateEvent.
За їх допомогою можна централізовано логувати або обробляти події.
userDomain.onCreateEffect(effect => {
effect.fail.watch(({ error }) => {
console.error('Помилка ефекту:', error)
})
})Таким чином, якщо в будь-якому ефекті всередині userDomain станеться помилка, вона перехопиться автоматично.
5. Ієрархія Domain'ів
Domains можуть вкладатися один в одного:
const appDomain = createDomain('app')
const userDomain = appDomain.createDomain('user')
const authDomain = appDomain.createDomain('auth')Це корисно для великих застосунків:
appDomain- кореневий, глобальні стани;userDomain- дані про користувача;authDomain- автентифікація і токени;cartDomain- кошик (в e-commerce);- і т.д.
6. Скидання і очищення Domain (життєвий цикл)
Effector дозволяє перестворювати Domain (наприклад, при logout):
import { fork, allSettled } from 'effector'
const scope = fork({ values: { $user: null } })
await allSettled(fetchUserFx, { scope, params: 1 })Це дає можливість:
- мати окремий стан для кожного клієнта (SSR, мульти-інстанси),
- очищати весь стан у domain при виході користувача.
7. Domain як "feature module"
Можна думати так:
userDomain
├── events/
│ └── userLoaded
├── stores/
│ └── $user
├── effects/
│ └── fetchUserFx
└── samples/
└── connect event → effectЦе фактично міні-застосунок всередині застосунку. Domain описує «що робить» конкретна частина системи.
8. Відмінність від звичайного коду без Domain
| Без Domain | З Domain | |
|---|---|---|
| Створення | createStore(), createEvent() | domain.createStore(), domain.createEvent() |
| Ізоляція | Все глобально | Всі сутності згруповані |
| Логування | Потрібно вручну | Можна централізувати |
| Помилки | Потрібно ловити окремо | Domain перехоплює |
| SSR | Потрібно очищати вручну | Можна клонувати цілий scope |
ПІДСУМОК
Domain - це контейнер (або модуль) Effector, у якому зберігаються всі пов'язані стани, події та ефекти. Він допомагає:
- структурувати код,
- керувати життєвим циклом стора,
- централізувати обробку помилок,
- ізолювати стан між користувачами і запитами.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.