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

Methods

serialize(scope, params)

A companion method for fork. It allows us to get a serialized value for all the store states within a scope. The main purpose is an application state serialization on the server side during SSR.

Requirements

Babel plugin or SWC plugin is required for using this method, as these plugins provide the SIDs for stores, which are required for stable state serialization.

You can find deep-dive explanation here

Formulae

serialize(scope: Scope, { ignore?: Array<Store<any>>; onlyChanges?: boolean }): {[sid: string]: any}

Arguments

  1. scope Scope: a scope object (forked instance)
  2. ignore Optional array of Store to be omitted during serialization (added 20.14.0)
  3. onlyChanges Optional boolean flag to ignore stores which didn’t change in fork (prevent default values from being carried over network)
Deprecated

Since effector 23.0.0 property onlyChanges is deprecated.

Returns

An object with store values using sids as a keys

Reminder

If a store does not have a sid, its value will be omitted during serialization.

Examples

Serialize forked instance state

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

const inc = createEvent();
const $store = createStore(42);
$store.on(inc, (x) => x + 1);

const scope = fork();

await allSettled(inc, { scope });

console.log(serialize(scope)); // => {[sid]: 43}

Try it

Using with onlyChanges

With onlyChanges, this method will serialize only stores which were changed by some trigger during work or defined in values field by fork or hydrate(scope). Once being changed, a store will stay marked as changed in given scope even if it was turned back to the default state during work, otherwise client will not update that store on its side, which is unexpected and inconsistent. This allows us to hydrate client state several times, for example, during route changes in next.js

import { createDomain, fork, serialize, hydrate } from "effector";

const app = createDomain();

/** store which we want to hydrate by server */
const $title = app.createStore("dashboard");

/** store which is not used by server */
const $clientTheme = app.createStore("light");

/** scope in client app */
const clientScope = fork(app, {
  values: new Map([
    [$clientTheme, "dark"],
    [$title, "profile"],
  ]),
});

/** server side scope of chats page created for each request */
const chatsPageScope = fork(app, {
  values: new Map([[$title, "chats"]]),
});

/** this object will contain only $title data
 * as $clientTheme never changed in server scope */
const chatsPageData = serialize(chatsPageScope, { onlyChanges: true });
console.log(chatsPageData);
// => {'-l644hw': 'chats'}

/** thereby, filling values from a server will touch only relevant stores */
hydrate(clientScope, { values: chatsPageData });

console.log(clientScope.getState($clientTheme));
// => dark

Try it

Contributors