useObserveTriggerable
Runs a reactive effect with a manual trigger() method and an ignoreUpdates escape hatch.
Built on useObserveIgnorable — lazy by default (immediate: false). trigger() immediately executes the effect with the current selector value, using ignoreUpdates internally so the manual call does not cause a reactive re-trigger.
useObserveTriggerable
Reactively watch a source, or manually trigger the effect at any time.
(no effect fired yet)
import { import useObservable
useObservable, import useObserveTriggerable
useObserveTriggerable } from "@usels/web";
function function Component(): void
Component() { const const source$: any
source$ = import useObservable
useObservable(0);
const { const trigger: any
trigger, const ignoreUpdates: any
ignoreUpdates } = import useObserveTriggerable
useObserveTriggerable( () => const source$: any
source$.any
get(), (value: any
value) => { any
console.any
log("source:", value: any
value); } );
// Reactive: effect fires when source$ changes const source$: any
source$.any
set(1);
// Manual: effect runs immediately with the current value const trigger: any
trigger();
// Ignored: effect is suppressed for this update const ignoreUpdates: any
ignoreUpdates(() => { const source$: any
source$.any
set(2); });}import { observable, observeTriggerable } from "@usels/web";
function Component() { "use scope" const source$ = observable(0);
const { trigger, ignoreUpdates } = observeTriggerable( () => source$.get(), (value) => { console.log("source:", value); } );
// Reactive: effect fires when source$ changes source$.set(1);
// Manual: effect runs immediately with the current value trigger();
// Ignored: effect is suppressed for this update ignoreUpdates(() => { source$.set(2); });}Manual trigger
Section titled “Manual trigger”trigger() executes the effect immediately with the current selector value. Useful for initializing side effects on demand or re-running a sync after an ignored update.
import { useObservable, useObserveTriggerable } from "@usels/web";
const remote$ = useObservable("");const local$ = useObservable("");
function MyComponent() { const { trigger, ignoreUpdates } = useObserveTriggerable( () => remote$.get(), (remoteValue) => { ignoreUpdates(() => { local$.set(remoteValue); }); } );
// Force a sync of remote → local on demand return <button onClick={trigger}>Sync now</button>;}import { observable, observeTriggerable } from "@usels/web";
const remote$ = observable("");const local$ = observable("");
function MyComponent() { "use scope" const { trigger, ignoreUpdates } = observeTriggerable( () => remote$.get(), (remoteValue) => { ignoreUpdates(() => { local$.set(remoteValue); }); } );
// Force a sync of remote → local on demand return <button onClick={trigger}>Sync now</button>;}Breaking two-way binding cycles
Section titled “Breaking two-way binding cycles”The same ignoreUpdates pattern as useObserveIgnorable — prevents circular reactive updates when syncing two observables.
import { useObservable, useObserveTriggerable, useWatch } from "@usels/web";
function Component() { const local$ = useObservable(""); const remote$ = useObservable("");
// Sync remote → local without triggering local → remote const { ignoreUpdates } = useObserveTriggerable( () => remote$.get(), (remoteValue) => { ignoreUpdates(() => { local$.set(remoteValue); }); } );
// Sync local → remote useWatch( () => local$.get(), (localValue) => { remote$.set(localValue); } );}import { observable, observeTriggerable, watch } from "@usels/web";
function Component() { "use scope" const local$ = observable(""); const remote$ = observable("");
// Sync remote → local without triggering local → remote const { ignoreUpdates } = observeTriggerable( () => remote$.get(), (remoteValue) => { ignoreUpdates(() => { local$.set(remoteValue); }); } );
// Sync local → remote watch( () => local$.get(), (localValue) => { remote$.set(localValue); } );}Eager mode (immediate: true)
Section titled “Eager mode (immediate: true)”Pass immediate: true to execute the effect on setup.
import { useObservable, useObserveTriggerable } from "@usels/web";
function Component() { const count$ = useObservable(0);
const { trigger } = useObserveTriggerable( () => count$.get(), (value) => { console.log("value:", value); }, { immediate: true } );}import { observable, observeTriggerable } from "@usels/web";
function Component() { "use scope" const count$ = observable(0);
const { trigger } = observeTriggerable( () => count$.get(), (value) => { console.log("value:", value); }, { immediate: true } );}export { observeTriggerable, type ObserveTriggerableReturn } from "./core";export type UseObserveTriggerable = typeof observeTriggerable;/** * Runs a reactive effect with an `ignoreUpdates` escape hatch and a manual `trigger()` method. * * Built on `observeIgnorable` — lazy by default (`immediate: false`). * `trigger()` immediately executes the effect with the current selector value, * using `ignoreUpdates` internally to prevent recursive re-triggering. * * @param selector - Observable, array of Observables, or reactive read function. * @param effect - Side-effect callback. * @param options - `{ immediate?, schedule? }` * @returns `{ ignoreUpdates, trigger, dispose }` * * @example * ```tsx twoslash * // @noErrors * import { useObserveTriggerable } from "@usels/core"; * import { observable } from "@legendapp/state"; * * const source$ = observable(0); * * const { trigger, ignoreUpdates } = useObserveTriggerable( * () => source$.get(), * (value) => { console.log("source:", value); } * ); * * // Manually run the effect with the current value * trigger(); * ``` */export declare const useObserveTriggerable: UseObserveTriggerable;