fork API
import { fork, type Scope } from "effector";Метод fork создает изолированный скоуп приложения. Он нужен для SSR, тестирования и локальной изоляции состояния — вы запускаете вычисления в копии без влияния на глобальные юниты.
Алгоритм работы
- Вы вызываете
fork, получая новый скоуп. - Если переданы
valuesилиhandlers, они применяются при создании этого скоупа. - Юниты, вызванные с этим скоупом, работают с изолированными значениями и обработчиками.
- Состояние читается через
scope.getState(store)или сериализуется черезserialize.
Виды конфигураций fork
Форма | Описание |
|---|---|
fork() | Создает новый чистый скоуп без предзаполненных данных и переопределений обработчиков. |
fork({ values?, handlers? }) | Создает скоуп с начальными значениями сторов и пользовательскими обработчиками эффектов. |
fork(domain, options?) | Устаревшая форма, требующая domain. Используйте fork({ values?, handlers? }), если нет зависимости от старой сигнатуры. |
Конфигурации
fork()
Создает новый прикладной скоуп без дополнительных настроек.
- Формула
fork(): Scope- Тип
type SerializedState = Record<string, unknown>;type StorePair<T = unknown> = [StoreWritable<T>, T];
export function fork(config?: { values?: StorePair<any>[] | SerializedState; handlers?: Array<[Effect<any, any, any>, Function]>;}): Scope;-
Особенности
- Возвращает новый скоуп без предзаполненных сторов и без замены обработчиков.
- Подходит, когда данные и побочные эффекты должны остаться неизменными (например, первый рендер на сервере).
-
Примеры
import { createStore, createEvent, fork, allSettled } from "effector";
const inc = createEvent();const dec = createEvent();const $counter = createStore(0);
$counter.on(inc, (value) => value + 1);$counter.on(dec, (value) => value - 1);
const scopeA = fork();const scopeB = fork();
await allSettled(inc, { scope: scopeA });await allSettled(dec, { scope: scopeB });
console.log($counter.getState()); // => 0console.log(scopeA.getState($counter)); // => 1console.log(scopeB.getState($counter)); // => -1- Возвращаемое значение
Новый скоуп.
fork({ values?, handlers? })
Позволяет задать начальные значения для сторов и переопределить обработчики эффектов внутри скоупа.
- Формула
fork({ values?, // например [[$store, value], ...] или сериализованный объект handlers?, // например [[effect, handler], ...]}): Scope- Тип
type SerializedState = Record<string, unknown>;type StorePair<T = unknown> = [StoreWritable<T>, T];
export function fork(config?: { values?: StorePair<any>[] | SerializedState; handlers?: Array<[Effect<any, any, any>, Function]>;}): Scope;-
Особенности
valuesможет быть массивом кортежей[$store, value]или объектом сериализованного состояния (обычно результатserialize); предпочтителен массив кортежей.handlersпринимает только массив кортежей, замены работают только в пределах созданного скоупа.- Значения и обработчики применяются один раз при создании скоупа и не обновляются автоматически.
-
Примеры
Задание начального состояния и подмена обработчика в тесте:
import { createEffect, createStore, fork, allSettled } from "effector";
const fetchFriendsFx = createEffect<{ limit: number }, string[]>(async ({ limit }) => { return [];});const $user = createStore("guest");const $friends = createStore<string[]>([]);
$friends.on(fetchFriendsFx.doneData, (_, result) => result);
const testScope = fork({ values: [[$user, "alice"]], handlers: [[fetchFriendsFx, () => ["bob", "carol"]]],});
await allSettled(fetchFriendsFx, { scope: testScope, params: { limit: 10 },});
console.log(testScope.getState($friends));// => ['bob', 'carol']Создание скоупа с сериализованным состоянием:
import { fork } from "effector";
const serialized = { userSid: "alice", ageSid: 21,};
const scope = fork({ values: serialized });- Возвращаемое значение
Новый скоуп с примененными values и handlers.
fork(domain, options?)
Устаревшая форма, требующая domain; актуальна только для совместимости со старым кодом.
Используйте fork({ values?, handlers? }), так как fork отслеживает юниты автоматически без передачи domain.
- Формула
fork(domain, { values?, // например [[$store, value], ...] или сериализованный объект handlers?, // например [[effect, handler], ...]}): Scope- Тип
type SerializedState = Record<string, unknown>;
export function fork( domain: Domain, config?: { values?: SerializedState | Array<[StoreWritable<any>, any]>; handlers?: Array<[Effect<any, any, any>, Function]>; },): Scope;-
Особенности
- Передача
domainнужна только в проектах, где код еще зависит от старой сигнатуры. - Допустимые форматы
valuesиhandlersсовпадают с конфигурацией безdomain.
- Передача
-
Пример
import { createDomain, createStore, fork } from "effector";
const app = createDomain();const $flag = app.createStore(false);
const scope = fork(app, { values: [[$flag, true]],});
console.log(scope.getState($flag)); // => true- Возвращаемое значение
Новый скоуп, привязанный к указанному domain.
Связанные API и статьи
- API
- Статьи
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.