Pay attention
This documentation is for the as yet unreleased version of effector Spacewatch 23.0.

fork

since

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

Formulae

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

Babel plugin or SWC plugin is required for using this method

Arguments

  1. domain (Domain): Optional domain to fork

  2. 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],
        ],
      });
    2. Map with stores and values:

      fork({
        values: new Map().set($user, "alice").set($age, 21),
      });
    3. 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

  3. handlers: Option to provide handlers for effects

    Can be used in two ways:

    1. Array of tuples with effects and handlers:

      fork({
        handlers: [
          [getMessageFx, (params) => ({ id: 0, text: "message" })],
          [getUserFx, async (params) => ({ name: "alice", age: 21 })],
        ],
      });
    2. Map with effects and handlers:

      fork({
        handlers: new Map()
          .set(getMessageFx, (params) => ({ id: 0, text: "message" }))
          .set(getUserFx, async (params) => ({ name: "alice", age: 21 })),
      });

Returns

Scope

Examples

Create two instances with independent counter state

import { createStore, createEvent, forward, fork, allSettled } from "effector";

const inc = createEvent();
const dec = createEvent();
const $counter = createStore(0)
  .on(inc, (value) => value + 1)
  .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

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([]).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

Contributors