useObserveIgnorable
Runs a reactive effect with an ignoreUpdates escape hatch. Changes made inside ignoreUpdates(updater) do not trigger the effect. Useful for breaking circular update cycles in two-way bindings.
useObserveIgnorable
Listening
Update the source normally or inside ignoreUpdates to suppress the effect.
(no effect fired yet)
import { import useObserveIgnorable
useObserveIgnorable, import useObservable
useObservable } from "@usels/web";
function function Component(): void
Component() { const const source$: any
source$ = import useObservable
useObservable(0);
const { const ignoreUpdates: any
ignoreUpdates, const isIgnoring$: any
isIgnoring$ } = import useObserveIgnorable
useObserveIgnorable( () => const source$: any
source$.any
get(), (value: any
value) => { any
console.any
log("source changed:", value: any
value); } );
// Normal change — effect fires const source$: any
source$.any
set(1);
// Ignored change — effect is suppressed const ignoreUpdates: any
ignoreUpdates(() => { const source$: any
source$.any
set(2); });}import { observeIgnorable, observable } from "@usels/web";
function Component() { "use scope" const source$ = observable(0);
const { ignoreUpdates, isIgnoring$ } = observeIgnorable( () => source$.get(), (value) => { console.log("source changed:", value); } );
// Normal change — effect fires source$.set(1);
// Ignored change — effect is suppressed ignoreUpdates(() => { source$.set(2); });}Breaking two-way binding cycles
Section titled “Breaking two-way binding cycles”The primary use case is preventing a reactive feedback loop when syncing two observables.
import { useObserveIgnorable, useObservable, useWatch } from "@usels/web";
function Component() { const local$ = useObservable(""); const remote$ = useObservable("");
// Sync remote → local without triggering local → remote const { ignoreUpdates } = useObserveIgnorable( () => remote$.get(), (remoteValue) => { ignoreUpdates(() => { local$.set(remoteValue); }); } );
// Sync local → remote useWatch( () => local$.get(), (localValue) => { remote$.set(localValue); } );}import { observeIgnorable, observable, watch } from "@usels/web";
function Component() { "use scope" const local$ = observable(""); const remote$ = observable("");
// Sync remote → local without triggering local → remote const { ignoreUpdates } = observeIgnorable( () => remote$.get(), (remoteValue) => { ignoreUpdates(() => { local$.set(remoteValue); }); } );
// Sync local → remote watch( () => local$.get(), (localValue) => { remote$.set(localValue); } );}Reactive isIgnoring$
Section titled “Reactive isIgnoring$”isIgnoring$ is an Observable that reflects whether an ignoreUpdates call is currently active.
import { observable, Show, useObserveIgnorable } from "@usels/web";
const count$ = useObservable(0);
function MyComponent() { const { ignoreUpdates, isIgnoring$ } = useObserveIgnorable( () => count$.get(), (value) => { console.log("count:", value); } );
return ( <Show if={isIgnoring$}> <span>Ignoring updates...</span> </Show> );}import { observable, observeIgnorable, Show } from "@usels/web";
const count$ = observable(0);
function MyComponent() { "use scope" const { ignoreUpdates, isIgnoring$ } = observeIgnorable( () => count$.get(), (value) => { console.log("count:", value); } );
return ( <Show if={isIgnoring$}> <span>Ignoring updates...</span> </Show> );}Eager mode (immediate: true)
Section titled “Eager mode (immediate: true)”Pass immediate: true to execute the effect immediately on setup.
import { useObserveIgnorable, useObservable } from "@usels/web";
function Component() { const count$ = useObservable(0);
const { ignoreUpdates } = useObserveIgnorable( () => count$.get(), (value) => { console.log("value:", value); }, { immediate: true } );}import { observeIgnorable, observable } from "@usels/web";
function Component() { "use scope" const count$ = observable(0);
const { ignoreUpdates } = observeIgnorable( () => count$.get(), (value) => { console.log("value:", value); }, { immediate: true } );}export { observeIgnorable, type ObserveIgnorableReturn } from "./core";export type UseObserveIgnorable = typeof observeIgnorable;/** * Runs a reactive effect with an `ignoreUpdates` escape hatch to suppress circular triggers. * * Built on `watch` — lazy by default (`immediate: false`). * Changes made inside `ignoreUpdates(updater)` do not trigger the effect. * Useful for two-way bindings where you need to break update cycles. * * @param selector - Observable, array of Observables, or reactive read function. * @param effect - Side-effect callback. Suppressed when triggered via `ignoreUpdates`. * @param options - `{ immediate?, schedule? }` * @returns `{ ignoreUpdates, isIgnoring$, dispose }` * * @example * ```tsx twoslash * // @noErrors * import { useObserveIgnorable } from "@usels/core"; * import { observable } from "@legendapp/state"; * * const source$ = observable(0); * * const { ignoreUpdates, isIgnoring$ } = useObserveIgnorable( * () => source$.get(), * (value) => { console.log("source:", value); } * ); * * // Update source without triggering the effect * ignoreUpdates(() => { source$.set(42); }); * ``` */export declare const useObserveIgnorable: UseObserveIgnorable;