Helper Functions
ObservableHint
These hints tweak the default behavior of observables to improve their performance.
ObservableHint.opaque
ObservableHint.opaque
marks an object in an observable as opaque so that it will be treated as a primitive, so that properties inside the opaque object will not be observable.
This is useful for storing DOM or React elements or other large objects in an observable when you don't care about tracking its properties changing.
import { observable, ObservableHint } from '@legendapp/state'
const state$ = observable({ text: 'hi', body: ObservableHint.opaque(document.body) })
ObservableHint.plain
ObservableHint.plain
marks an object as not having any child functions or observables. By default observables recurse through their children to find these and setup computed observables and observable links. This is a performance optimization to prevent needing to do that.
import { observable, ObservableHint } from '@legendapp/state'
const bigObject = {}
const state$ = observable({ text: 'hi', child: ObservableHint.plain(bigObject) })
mergeIntoObservable
If you want to merge a deep object into an observable, mergeIntoObservable
can do that and retain all of the existing observables and listeners on the way, and fire listeners as values change.
import { observable } from "@legendapp/state";
import { mergeIntoObservable } from "@legendapp/state";
const state$ = observable({ store: { text: "hello", other: "hello there" } });
state$.store.text.onChange(({ value }) =>
console.log(`text changed to "${value}"`)
);
const newValue = { store: { text: "hi", other: "hi there" } };
mergeIntoObservable(state$, newValue);
// text changed to "hi"
state$.store === newValue.store; // ✅ true
trackHistory
trackHistory
creates an observable that tracks all changes in the target observable, with the previous value at the time it was changed.
import { observable } from '@legendapp/state'
import { trackHistory } from '@legendapp/state/helpers/trackHistory'
const state$ = observable({ profile: { name: 'Hello' }})
// Track all changes to state
const history = trackHistory(state$)
// Change something in state
state$.profile.name.set('Annyong')
// History shows the previous value when it changed:
{
1666593133018: {
profile: {
name: 'Hello'
}
}
}
undoRedo
undoRedo
is similar to trackHistory in that it tracks changes to an observable. However, undoRedo
also provides helpers for undo / redo (as the name suggests) and does the tracking for you.
import { observable } from "@legendapp/state";
import { undoRedo } from "@legendapp/state/helpers/undoRedo";
const state$ = observable({ todos: ["Get milk"] });
const { undo, redo, getHistory } = undoRedo(state$.todos, { limit: 100 });
state$.todos.push("Pick up bread");
// todos is now ["Get milk", "Pick up bread"]
undo();
// todos is now back to ["Get milk"]
redo();
// todos is restored to ["Get milk", "Pick up bread"]