Skip to main content

Scope

Scope is a fully isolated instance of application. The primary purpose of scope includes SSR (but is not limited to). Scope contain independent clone of all the units (including connections between them) and basic methods to access them. Scope can be created by fork

interface Scope {
getState<T>(store: Store<T>): T
}

Imperative effects calls with scope

Imperative effects calls are supported in effect handlers but not in watch functions.

When effect call another effects then it should call only effects, not common async functions and effect calls should have awaited:

Correct, effect without inner effects:

const delayFx = app.createEffect(async () => {
await new Promise(rs => setTimeout(rs, 80))
})

Correct, effect with inner effects:

const authUserFx = app.createEffect()
const sendMessageFx = app.createEffect()

const sendWithAuthFx = app.createEffect(async () => {
await authUserFx()
await delayFx()
await sendMessageFx()
})

Incorrect, effect with inner effects:

const sendWithAuthFx = app.createEffect(async () => {
await authUserFx()
//WRONG! wrap that in effect
await new Promise(rs => setTimeout(rs, 80))
//context lost
await sendMessageFx()
})

So, any effect might either call another effects or perform some async computations but not both.

tip

Consider using attach instead of imperative call

Scope methods

getState

Returns store value in given scope

Example

Create two instances of application, call events in them and test $counter store value in both

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

Try it