Scope
Независимый изолированный инстанс приложения, содержит копию всех юнитов (включая связи между ними) и основные методы для доступа к ним.
Основные области применения - реализация SSR и тестирование приложения.
Scope может быть создан с помощью fork
Формула
interface Scope {
getState<T>(store: Store<T>): T
}
Методы
getState
Возвращает значение стора в данном scope
scope.getState<T>(store: Store<T>): T
Пример использования getState
Создание двух инстансов приложения, вызов событий в них и проверка сохранения значения стора $counter
в каждом из них
import {
createStore,
createEvent,
createDomain,
forward,
fork,
allSettled,
} from 'effector'
const domain = createDomain()
const inc = domain.createEvent()
const dec = domain.createEvent()
const $counter = domain
.createStore(0)
.on(inc, value => value + 1)
.on(dec, value => value - 1)
const scopeA = fork(domain)
const scopeB = fork(domain)
await allSettled(inc, {scope: scopeA})
await allSettled(dec, {scope: scopeB})
console.log($counter.getState()) // => 0
console.log(scopeA.getState($counter)) // => 1
console.log(scopeB.getState($counter)) // => -1
Императивные вызовы эффектов и scope
Если эффект вызывает другие эффекты, то он может вызывать только эффекты, а не обычные асинхронные функции, и вызовы эффектов должны иметь await:
Правильно, эффект без внутренних эффектов:
const delayFx = app.createEffect(async () => {
await new Promise(rs => setTimeout(rs, 80))
})
Правильно, эффект с внутренними эффектами:
const authUserFx = app.createEffect()
const sendMessageFx = app.createEffect()
const sendWithAuthFx = app.createEffect(async () => {
await authUserFx()
await delayFx()
await sendMessageFx()
})
Неправильно, эффект с внутренними эффектами после обычных асинхронных вызовов:
const sendWithAuthFx = app.createEffect(async () => {
await authUserFx()
//НЕ ПРАВИЛЬНО! этот код следует сделать отдельным эффектом delayFx
await new Promise(rs => setTimeout(rs, 80))
//потеря контекста
await sendMessageFx()
})
Таким образом, любой эффект может либо вызывать другой эффект, либо выполнять некоторые асинхронные вычисления, но не то и другое
Вместо императивных вызовов оптимальнее использовать attach
Императивные вызовы эффектов поддерживаются только в обработчиках других эффектов, не в watch
функциях