import { fork, type Scope } from "effector";

Methods

fork()

since

introduced in effector 22.0.0

Creates an isolated instance of application. Primary purposes of this method are SSR and testing.

Formulae

fork(): Scope

Returns

Scope: New fresh scope

Examples

Create two instances with independent counter state

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()); // => 0
console.log(scopeA.getState($counter)); // => 1
console.log(scopeB.getState($counter)); // => -1

Try it

fork(options)

Allows to set values for stores in scope and replace handlers for effects.

since

support for array of tuples in values and handlers introduced in effector 22.0.0

Formulae

fork(options: { values?, handlers? }): Scope

Arguments

  1. options: { values?, handlers? } โ€” Object with optional values and handlers

values

Option to provide initial states for stores.

Can be used in three ways:

  1. Array of tuples with stores and values:
fork({
  values: [
    [$user, "alice"],
    [$age, 21],
  ],
});
  1. Map with stores and values:
fork({
  values: new Map().set($user, "alice").set($age, 21),
});
  1. Plain object: {[sid: string]: value}
fork({
  values: {
    [$user.sid]: "alice",
    [$age.sid]: 21,
  },
});

Explanation

Such objects are created by serialize, in application code array of tuples is preferred

handlers

Option to provide handlers for effects.

Can be used in different ways:

  1. Array of tuples with effects and handlers:
fork({
  handlers: [
    [getMessageFx, (params) => ({ id: 0, text: "message" })],
    [getUserFx, async (params) => ({ name: "alice", age: 21 })],
  ],
});
  1. Map with effects and handlers:
fork({
  handlers: new Map()
    .set(getMessageFx, (params) => ({ id: 0, text: "message" }))
    .set(getUserFx, async (params) => ({ name: "alice", age: 21 })),
});
  1. Plain object: {[sid: string]: handler}
fork({
  handlers: {
    [getMessageFx.sid]: (params) => ({ id: 0, text: "message" }),
    [getUserFx.sid]: async (params) => ({ name: "alice", age: 21 }),
  },
});

deprecation

Such objects are deprecated since effector 23.0.0 and will be removed in future versions. Array of tuples is preferred.

Returns

Scope: New fresh scope

Examples

Set initial state for store and change handler for effect

This is an example of test, which ensures that after a request to the server, the value of $friends is filled.

import { createEffect, createStore, fork, allSettled } from "effector";

const fetchFriendsFx = createEffect<{ limit: number }, string[]>(async ({ limit }) => {
  /* some client-side data fetching */
  return [];
});
const $user = createStore("guest");
const $friends = createStore([]);

$friends.on(fetchFriendsFx.doneData, (_, result) => result);

const testScope = fork({
  values: [[$user, "alice"]],
  handlers: [[fetchFriendsFx, () => ["bob", "carol"]]],
});

/* trigger computations in scope and await all called effects */
await allSettled(fetchFriendsFx, {
  scope: testScope,
  params: { limit: 10 },
});

/* check value of store in scope */
console.log(testScope.getState($friends));
// => ['bob', 'carol']

Try it

fork(domain, options?)

since

Introduced in effector 21.0.0

Deprecated

Since effector 23.0.0.

fork no longer requires domain as an argument, because it can automatically track all units starting from effector 22.0.0.

Formulae

fork(domain: Domain, options?: { values?, handlers? }): Scope

Arguments

  1. domain (Domain): Optional domain to fork.
  2. options: { values?, handlers? } โ€” Object with optional values and handlers

Returns

Scope: New fresh scope

Examples

TBD

Contributors